网站可访问性缺陷堆积如山,怎样用数据归类法逐个击破?

2,352字
10–15 分钟
in

自动化检测工具甩来几百条错误报告,是不是直接裂开?别慌,这玩意儿就跟收到一堆外卖差评似的——看着吓人,但扒拉扒拉会发现好多都是同一家店把香菜放错了。一场技术大会上的老司机分享了一个骚操作:把那些乱糟糟的报错导出来,塞进表格里重新归类,居然直接干掉了一半的任务量。这篇博客就唠唠这个去重+分组的野路子,手把手带小白理清那一大坨可访问性(Accessibility)烂账。

目录

啥是积压

可访问性积压,就是网站上一堆没修的障碍缺陷。好比屋子角落攒的快递盒,自动扫出来的每个报错都是一个盒子。但很多盒子里的东西其实一样——同一个“图片缺描述”的毛病,可能在几十个页面里反复出现。关键不是挨个拆,而是先分分类。

先搞张Excel

导出原始数据

用 Lighthouse、axe 这类工具跑一遍全站,拿到 CSV 或 JSON 格式的报告。这步没啥技术含量,点一下“导出”按钮的事儿。不过有个坑:工具默认可能只扫了首页,得手动设置成深度抓取(比如爬个200个URL)。不然拿到的数据不全,后面白折腾。

挪进Notion或表格

Dave 当时把 Excel 贴到 Notion 里,因为 Notion 能随便拖拽列、隐藏没用的字段。普通用户直接用 WPS 或 Google Sheets 也一样。打开文件后,第一时间把“行号”、“检测规则ID”这类不重要的列右键隐藏掉,屏幕上只留“错误描述”、“页面路径”、“影响等级”这三四列。眼睛清爽了,脑子才能转。

示例:原始报错长这样

页面URL错误类型详细描述
/about图片缺altimg标签无替代文本
/product/1图片缺altimg标签无替代文本
/about对比度低文字与背景色比例不足

一看就明白:第一行和第三行是不同问题,但前两行根本是同一个毛病。如果直接修,得改两个文件。但聪明人不会这么干。

去重大法

按描述关键字分组

在表格里新增一列叫“分类标签”。手动把每条错误的描述简化成核心词。比如“img标签无替代文本”统一写成“缺alt”,“按钮无文本标签”写成“缺aria-label”。这步有点费手指,但千万别偷懒用自动筛选——因为不同工具的报错措辞不一样(“缺少可访问名称”和“无无障碍标签”其实是同一回事)。人工过一遍,能把相似项归到同一堆。

分组结果示例

分类标签出现次数影响页面示例
缺alt47/about, /product/1, /contact
对比度低23/home, /blog/post/5
缺aria-label12/search, /modal

看见没?47个“缺alt”其实只需要改一次全局组件(比如图片模板)。实际要动手修的问题类型只有3种,而不是表面上的82个独立任务。

砍掉重复项后的清单

把相同分类只保留一行,新建一个“待办列表”。这时清单长度基本只剩原来的零头。Dave 说他砍掉了近50%的票,有时候甚至能砍到70%。举个栗子:一个电商网站有500个商品页,每个页面的“缺alt”都单独报一次错——看着是500个issue,实际上就1种修复方法。

按歧视强度排优先级

给每个分类贴伤害标签

不是所有障碍都一样可恨。一个色盲用户看不清灰色按钮,和全盲用户完全点不了无标签的提交按钮,后者严重得多。打开 Notion 里的分组表,新增一列“影响人群”,填上“盲人”、“低视力”、“行动障碍”等。然后按这个排序:那些直接阻止某人完成核心操作的分类,必须排最前面

伤害等级参考表

分类影响人群是否阻塞操作
缺alt盲人
缺aria-label屏幕阅读器用户
键盘陷进行动障碍

当时 Dave 整理完后,发现自家产品有几十处“缺aria-label”让读屏软件直接哑巴了。这种属于“歧视性缺陷”,得马上修。而“对比度低”虽然烦人,但不至于让人用不了网站,可以往后放。

动手修三个案例

修缺alt

找到所有 <img> 标签所在的模板文件。如果是 Vue/React 组件,改一个地方就同步所有页面。加属性:alt="描述商品或功能的文本"千万别写成 alt="" 除非是纯装饰图——装饰图得配上 role="presentation" 才干净。

<!-- 错误写法 -->
<img src="cat.jpg">

<!-- 正确写法 -->
<img src="cat.jpg" alt="一只橘猫趴在键盘上">

修缺aria-label

针对那些没有文字但有点击功能的元素(比如关闭按钮 ×)。直接塞一个看不见的标签。

<button aria-label="关闭弹窗">×</button>

坑点提醒aria-label 会覆盖按钮里的可见文字。如果按钮本身已经有“关闭”两个字,就别再画蛇添足。

修键盘陷进

有些模态框弹出来后,按Tab键会跑到背景页面里去。这得用 JavaScript 抓焦点。在模态框打开时,把焦点锁在内部第一个可聚焦元素上;关闭时还回去。原生 <dialog> 元素已经自带一部分这功能,但老项目得手写。

// 打开弹窗后
modal.addEventListener('shown', () => {
  focusableElements[0]?.focus();
});

用容器单位搞响应式(顺带提一嘴)

跟可访问性无关,但大会上 Chris 秀了个新玩法:用 cqi 代替 vw 做流体字号。以前写 font-size: clamp(1rem, 1rem + 2vw, 2rem),现在改成 clamp(1rem, 1rem + 1cqi, 2rem)。区别在于 cqi 相对父容器宽度变化,而不是视口。好处是卡片组件放到任何地方,字号都跟着自己所在的盒子缩放,不会因为屏幕宽就无脑变大。老项目别急着全换,先在独立组件里试试水。


最后补一嘴:别信自动化工具给的那个总错误数。那数字就像超市小票上的“节省金额”——看着很爽,但水分大得很。把问题导出来、归归类、砍掉重复的、按对真实人类的伤害程度排序,比对着原始列表瞎修要香一万倍。