html可访问性测试必须在真实浏览器中验证焦点流、语义树和键盘行为;chrome devtools可访问性面板能实时查看role、name、states,禁用css后检查语义骨架,用getbyrole编写测试,并需真机测试voiceover焦点与触摸目标。

HTML可访问性测试不能只跑一遍W3C校验就完事,必须在真实浏览器中验证焦点流、语义树和键盘行为——jsdom里测出来的通过,真机上VoiceOver可能完全“摸不到”按钮。
用 Chrome DevTools 直接看可访问性树
别靠肉眼猜哪个元素能被屏幕阅读器读到。打开 Elements 面板,右键任意元素 →「Inspect Accessibility Properties」,就能看到它在可访问性树里的 role、name、states(如 disabled、aria-expanded)是否完整。常见错误包括:
-
button没有可见文本也未设aria-label,name 显示为 “(empty)” -
div加了role="button",但没加tabindex="0",无法键盘聚焦 -
nav缺aria-label,VoiceOver 只报 “region”,不报“主导航”
这个面板比任何静态分析都准,因为它是浏览器实时构建的可访问性树,不是 DOM 快照。
禁用 CSS 后检查语义骨架是否仍可用
在 Chrome DevTools 的 Command Menu(Cmd+Shift+P)里输入 “Disable styles”,回车。页面只剩纯语义结构后,做三件事:
- 按
Tab键走一遍焦点流:所有交互元素是否依次可达?h1~h3是否还能被识别为标题层级? - 看
nav、main、footer是否仍保留在 DOM 中,没被display: none或visibility: hidden干掉 - 确认按钮、链接等仍有默认焦点环(哪怕只是浏览器默认样式),否则说明它们依赖 CSS 才“存在”
很多“视觉正常”的菜单,在禁用 CSS 后变成一串无意义的 div,这就是语义塌方——无障碍场景下等于不可用。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
用 getByRole 写测试,而不是 querySelector
getByRole 是目前最贴近用户操作的查询方式,它查的是可访问性树,不是 DOM 树。写法上必须带 name 参数:
screen.getByRole('button', { name: '提交表单' })
不写 name 就会报错,这不是 bug,是提醒你组件缺语义标识。注意几个关键点:
- 禁用态必须用
await expect(el).toBeDisabled()断言,不能只看disabled属性——有些组件用aria-disabled="true"模拟,toBeDisabled()才真正检查浏览器是否阻止了焦点和点击 - 展开/收起按钮必须同步
aria-expanded,且断言expect(button).toHaveAttribute('aria-expanded', 'true') - 图标按钮如
<button><svg></svg></button>,若无文字,必须显式加aria-label,否则getByRole('button')找不到
用 querySelector 查 button[disabled] 看似简单,但绕过了可访问性树,等于在测字符串,不是测用户能不能用。
移动端真机测试不可跳过
Chrome 模拟器再像,也模拟不出 iOS VoiceOver 的焦点滑动逻辑和触摸延迟。必须在真机上做两件事:
- 用手指双指从屏幕顶部向下滑,看焦点是否逐个落在可触元素上;相邻按钮间距小于 8px 时,VoiceOver 常连跳两个
- 点按按钮后观察是否有视觉反馈(哪怕只是
:active背景色变化);原生button自带该行为,div+onclick不会触发 - 测量实际触摸目标尺寸:用 DevTools 的「Toggle device toolbar」选设备后,右键元素 →「Show DOM properties」,看
clientWidth×clientHeight是否 ≥ 48×48 —— padding 撑出来的不算,transform 缩放后的也不算
DOM 深度超过 6 层时,低端安卓机上 touchstart 延迟会翻倍,这点在模拟器里根本测不出来。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










