HTML页面可访问性得分本身不值得追求,真正要盯的是「关键路径是否可操作」和「核心内容是否可感知」;必须当天修复alt缺失、label未绑定、tabindex="-1"误用三类问题,因其直接导致用户在登录、表单提交等核心任务中卡死。

直接说结论:HTML页面可访问性得分本身不值得追求,真正要盯的是「关键路径是否可操作」和「核心内容是否可感知」。axe、WAVE 或 Lighthouse 给出的 85/100 分,可能掩盖了登录按钮无法键盘聚焦、商品图缺失 alt、错误提示不朗读等致命问题。
怎么判断哪些可访问性问题必须优先修复
- 修复顺序不能按“报错数量”排,得按「用户实际卡点」排
- 关键路径指:用户完成核心任务(如搜索、加购、提交表单)所依赖的最小 DOM 集合
- 必须当天修复的三类问题:
alt缺失(功能性图片)、label未绑定(所有input/select/textarea)、tabindex="-1"误用在非容器元素上 - 可暂缓的:纯装饰性
aria-label补充、role="status"位置微调、aria-describedby指向的文案润色 - 用 Chrome DevTools → Accessibility 面板 点开任意控件,看「Name」和「Role」字段是否为空——空就代表屏幕阅读器根本读不出它
怎么快速验证 label 是否真正生效
- 不要看视觉对齐或 placeholder 文字,那对辅助技术完全无效
- 打开 NVDA 或 VoiceOver,进入表单页,按
Insert + F7(NVDA)或VO + U(VoiceOver)调出元素列表,确认每个输入框旁是否出现对应标签文字 - 检查两种绑定方式是否都合规:
- 包裹式:
<label>邮箱<input id="email" type="email"></label>(推荐,无 id 冲突风险) - 分离式:
<label for="email">邮箱</label><input id="email" type="email">(id值必须唯一、不能含空格或句点)
- 包裹式:
- 禁用任何用
aria-label替代label的写法——它绕过原生语义,且在 Safari + VoiceOver 组合下常失效
怎么处理动态内容更新后的可访问性断层
- AJAX 提交后没反馈?不是 JS 没执行,是屏幕阅读器根本不知道 DOM 变了
- 错误消息必须用
aria-live="polite"包裹,且该元素需:- 在 DOM 中位置靠前(建议紧贴
<form>开头) - 初始状态不可见但不能用
display: none(会从可访问树中移除) - 推荐用
visibility: hidden; position: absolute; clip: rect(0 0 0 0);隐藏
- 在 DOM 中位置靠前(建议紧贴
- 表单校验失败时,除了视觉高亮,还必须:
- 给出错
input加aria-invalid="true" - 用
aria-describedby="error-123"指向错误消息的id
- 给出错
- 模态框打开后,必须同时设置:
-
role="dialog" -
aria-modal="true" -
aria-labelledby指向标题元素(如<h2 id="modal-title">登录</h2>)
-
真正难的不是加属性,而是改结构。比如把 <div class="btn" onclick="submit()">提交</div> 改成 <button>提交</button>,表面只换一个标签,实则解决了键盘聚焦、Enter/Space 触发、:active 样式、touchstart 延迟、VoiceOver 识别五连问。这类重构没法靠脚本批量扫出来,得人工逐个翻 DOM 树确认。



















