1245 字
6 分钟

可访问性体检:三个真问题与三次假警报

用脚本给自己的静态博客做了一次可访问性体检:重复 id、搜索框没有无障碍名称、键盘焦点环在深色背景上几乎看不见。同时记录体检脚本自己报过的三次假警报——它们比漏报更危险。
10月24日 23:00

SEO 体检做久了会形成一个偏见:只关心搜索引擎看不看得懂。但同一批标记,屏幕阅读器和键盘用户也在用——比如 h1 结构、图片 alt、表单的无障碍名称。

这轮我给博客做了一次可访问性体检,查出三个真问题,也踩到三次「体检脚本自己骗人」。

六项检查,跑一遍就知道#

体检脚本的输出:改前有重复 id、三个搜索框没有无障碍名称

检查判据
lang<html lang> 存在且正确
重复 id同一页面内 id 不重复(重复 id 是非法 HTML,锚点与 aria-labelledby 都会失准)
图片 alt没有缺 alt 的 <img>
无障碍名称每个可聚焦元素都要有可见文本 / aria-label / title
对比度文字与背景的对比度 ≥ 4.5:1(大字 ≥ 3:1)
减少动效CSS 里有 prefers-reduced-motion 分支

实现都是十几行 DOM 查询,不需要装任何依赖。

三个真问题#

1. 每个页面都有两个 id="sidebar"。

外层网格容器(MainGridLayout)和侧栏组件内部(SideBar)用了同一个 id。重复 id 不会报错、页面也照常显示,但:

  • 锚点跳转(#sidebar)只会跳到第一个;
  • aria-labelledby 指向它时,读屏可能读到错的那个。

修法是把内层改成 id="sidebar-inner"——改之前先确认没有任何 CSS/JS 依赖 #sidebar(我扫了一遍,确实没有)。

2. 三个搜索框都没有无障碍名称。

它们只有 placeholder="搜索"。而 placeholder 有两个问题:输入内容后会消失,而且它不保证被当作可访问名称。读屏用户 Tab 到输入框时,听到的是一个没有标签的文本框。

修法是补 aria-label="搜索文章"——三个 input(桌面版、移动版、搜索面板内)都要补。

3. 键盘焦点环在深色背景上几乎看不见。

这条最隐蔽,因为我第一版体检把它判成了「通过」:outline: auto 1px —— 轮廓确实存在。但截图一看:

第二个 Tab 焦点: 归档 | outline: auto 1px rgb(16, 16, 16)

rgb(16,16,16) 是近黑色,压在本站 #0f1219 的深色背景上,等于没有。

修法是统一焦点样式,只在键盘导航时出现:

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
    border-radius: 4px;
}

改完再量,轮廓变成 solid 2px oklch(0.7 0.15 255)——主题蓝色,Tab 走一遍能清楚地看到光标在哪。

Tab 两次后的焦点:主题色描边清晰可见

三次假警报(比真问题更值得记)#

体检脚本自己报过的三次假警报

① 性能脚本报 LCP 1.9 秒。 真因是启动参数里带了 --host-resolver-rules=MAP * ~NOTFOUND(当初为了绕开本机代理),把所有第三方域名都解析成不存在——测出来的是「没有第三方的平行世界」。真实现场是 12 秒。

② SEO 脚本报 10 条「canonical 指向别处」。 真因是中文标签页的 canonical 是 percent-encoded 形式,两者等价,但脚本逐字符比较。改成比较前 unquote() 两边。

③ a11y 脚本报对比度 ratio 1.12(几乎全白 on 全白)。 真因是脚本没把文字颜色的 alpha 与背景合成:text-50 这类半透明文字、sr-only 这类收成 1px 的视觉隐藏元素全被算进了分母。

为什么假警报比漏报更危险:漏报只是没发现问题;假警报会让人去改本来没问题的东西——我差点为了「对比度不达标」去调深色主题的文字色,实际那两处一处是视觉隐藏的 h1、一处是半透明计数。

所以写体检脚本时,我给自己定了两条规矩:

  1. 每条判据都要能解释:「为什么这个元素不达标」要能打印出具体值(颜色、比例、坐标),而不是只给一个结论;
  2. 先怀疑脚本,再改代码:同一个「问题」出现在全站每个页面时,八成是判据写错了,而不是模板全错。

现在的基线#

lang            zh-CN
重复 id         0
图片缺 alt      0
无障碍名称      全部有(3 个搜索框已补 aria-label)
对比度          0 处不达标(大字 ≥3:1、正文 ≥4.5:1)
键盘焦点        主题色 2px 描边,Tab 全程可见
减少动效        prefers-reduced-motion 已支持

小结#

可访问性体检的收益不只是「对残障用户友好」:

  • 重复 id / 缺 alt / 无名称的按钮,对爬虫也是语义噪声;
  • 可见焦点环让键盘用户能用——而这个站自己就是写技术的,读者里有一半会按 Tab;
  • 更重要的是,它逼我把「我以为通过了」变成「量出来的结果」。

三行命令就能跑一遍,我把它和 SEO 体检放在同一个目录里,发文章前一起跑。

体检的具体判据与九类历史问题整理在站内 SEO 体检清单里,两套体检可以一起跑。

这篇文章是否对你有帮助?

发现错误或想要改进这篇文章?

在 GitHub 上编辑此页

文章修订历史 (1 次)

查看变更记录
10月24日 23:18:07 c20be15

docs(baseline): 第 30 轮终检——数字更新到最终状态,补第 28~30 轮小结

可访问性体检:三个真问题与三次假警报
作者
peroe
发布于
10月24日 23:00
许可协议
CC BY-NC-SA 4.0

相关文章