alt、label、lang缺失或无效是可访问性断裂主因:img缺alt致屏幕阅读器失效,input无label使键盘用户不知控件用途,html缺lang让VoiceOver无法正确发音。
可访问性问题大多从基础属性开始,alt、label、lang 这三个属性漏填或乱填,直接导致屏幕阅读器失效、搜索引擎无法理解内容、键盘导航断裂。
常见错误现象包括:img 标签没写 alt,写了但值是 alt="图片" 或 alt="icon";input 没配 label,或 for 属性指向一个不存在的 id;整个页面 html 标签缺 lang 属性。
img:not([alt]) 和 img[alt=""] 要分开对待:前者必须补描述,后者仅允许用于纯装饰图input:not([id]) + label[for] 组合必须成对出现;若用 aria-label 替代,得确认它没被 JS 动态覆盖html:not([lang]) 是硬伤,哪怕只写 lang="zh-CN" 也能让 VoiceOver 正确发音辅助技术依赖语义结构跳转,nav、main、header 等原生标签不是“锦上添花”,而是导航路径的锚点。用 div 套一堆 class 模拟,document.querySelector('nav') 就查不到,AT(辅助技术)也识别不了。
标题跳级(如 h1 后直接 h3)、section 没配 h2–h6、main 内部嵌套多个 div 却无明确语义划分,都会让读屏软件逻辑错乱。
立即学习“前端免费学习笔记(深入)”;
Document has a <code>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 是两回事。JS 动态插入、框架渲染、甚至非法嵌套都会让 Elements 面板呈现“看起来正常”的结构,但语义已崩坏——比如 p 里塞 div,浏览器会自动闭合 p,把 div 踢到外面,变成孤立节点。
这种节点不会报错,但 document.querySelector('nav') 找不到它,CSS 选择器也匹配不到,屏幕阅读器完全忽略。
document.querySelectorAll('*').forEach(el => { if (!el.parentElement) console.log('孤立元素:', el) }),揪出所有没爹的元素真正难的不是发现低可访问性,而是接受:HTML 源码只是意图草稿,真实可访问性只存在于浏览器解析后的 DOM 结构 + 辅助技术实际读取路径中。绕开这个前提去修样式、补 JS patch,只会让问题更隐蔽。