代码审查中快速识别低可访问性:检查alt、label、lang属性是否缺失,验证地标元素与标题层级是否断裂,用键盘导航测试焦点流完整性,并警惕浏览器解析后DOM与源码的差异。
可访问性这东西,说难也不难,但一不留神就会踩坑。我们聊一聊在代码审查时,怎么快速锁定那些“看不见”的坑。先说几个核心判断:真正让辅助技术“罢工”的,往往不是什么高深玄学,而是最基础的那几个属性漏了、填错了。

长期稳定更新的攒劲资源: >>>点此立即查看<<<
说起来,大部分可访问性翻车,追根溯源都栽在最基础的那几个属性上。alt、label、lang,这三个家伙但凡漏掉一个或者填得不对,屏幕阅读器就直接“哑火”,搜索引擎也读不懂你页面在说什么,键盘导航更是直接断掉。
实际代码里常见的情况是:img 标签上 alt 完全没写,或者写了等于没写——比如 alt="图片" 或 alt="icon",这种跟没写也没有什么区别;input 没有配 label,或者 label 的 for 属性指向了一个根本不存在的 id;整个 html 标签直接缺了 lang 属性。这些都属于硬伤。
img:not([alt]) 和 img[alt=""] 是两种完全不同的场景,要分开对待。前者必须补上描述性文字,后者只允许用在纯装饰性图片上。input:not([id]) 配上 label[for] 的组合必须成对出现,缺一不可。如果用了 aria-label 来替代,那得确认它没有被 JavaScript 动态覆盖掉。html:not([lang]) 是绝对的硬伤,即使只写一个 lang="zh-CN",也能让 VoiceOver 这类工具正确发音,不至于读出一堆乱码。辅助技术之所以能快速跳转页面,靠的是语义结构。像 nav、main、header 这些原生标签,它们不是“锦上添花”的装饰,而是整个导航路径的锚点。如果用 div 套一堆 class 来模拟,document.querySelector('nav') 根本查不到,辅助技术也就识别不了。
标题跳级也是常见问题——比如 h1 后面直接跟 h3,section 没有配 h2 到 h6,或者 main 内部嵌套了一堆 div 却没有明确语义划分。这些都会让读屏软件的逻辑变得混乱不堪。
main element”和“Headings don’t skip levels”这两项。nav、main 这样的节点,而不是 div role="navigation" 这种挂羊头卖狗肉的做法。document.querySelectorAll('h1, h2, h3, h4, h5, h6'),检查返回的标题数组是否严格递增或者持平——比如 h2 后面可以接 h2,但不能直接跳到 h4。自动化工具能扫出来的问题终究有限,像“焦点陷阱”、“焦点丢失”、“顺序错乱”这些,必须靠人手拿着 Tab 键走一遍。鼠标能点到的地方,键盘未必能进;视觉上看连续的区块,Tab 键可能直接跳过。
典型问题通常是:模态框打开后焦点没锁定在内部,关闭后焦点也没回退到触发按钮;div 模拟按钮忘了加 tabindex="0";display: none 的元素居然还残留在 tabindex 流里。
iframe 后,Tab 键能不能自然出来;进入弹窗后,按 Esc 能不能关闭且焦点回归原位。Focusable 和 Keyboard focusable 是否为 true。你写的 HTML 和浏览器最终生成的 DOM 是两回事。JavaScript 动态插入、框架渲染,甚至非法的嵌套结构,都会让 Elements 面板呈现出一个“看起来正常”的 DOM,但语义层早就崩了。比如 p 标签里塞一个 div,浏览器会自动闭合 p,把 div 踢到外面,变成孤立节点。
这种节点浏览器不会报错,但 document.querySelector('nav') 找不到它,CSS 选择器也匹配不到,屏幕阅读器直接忽略。
document.querySelectorAll('*').forEach(el => { if (!el.parentElement) console.log('孤立元素:', el) }),揪出所有没有父节点的元素。真正难的不是发现低可访问性,而是接受一个事实:HTML 源码只是意图草稿,真实可访问性只存在于浏览器解析后的 DOM 结构,加上辅助技术实际读取的路径中。绕开这个前提去修样式、补 JavaScript 补丁,只会让问题变得更加隐蔽。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述