屏幕阅读器依赖而非,因其自带role="navigation"并被nvda、jaws、voiceover识别为可跳转地标,支持d键等快捷导航;而无内置语义,需手动补全aria属性且易遗漏焦点与状态逻辑。

因为屏幕阅读器不“看”样式,只“读”语义;没有语义标签,视障用户面对的是一整页无法导航、无法理解的“空白块”。
screen reader 为什么依赖 nav 而不是 div class="nav"
主流读屏工具(NVDA、JAWS、VoiceOver)通过 DOM 中的隐式 ARIA role 构建可访问性树,nav 自带 role="navigation",支持快捷键跳转(如 NVDA 的 D 键);而 div class="nav" 没有角色信息,除非手动补 role="navigation" + aria-label,漏一个就失效。更关键的是:nav 会自动管理子元素焦点逻辑,比如展开/收起菜单时同步 aria-expanded,div 需要 JS 全手动实现——实际项目中极易遗漏。
main 缺失或重复时,视障用户根本找不到正文
main 是页面中唯一代表核心内容的容器,它的存在、唯一性和嵌套位置,直接决定屏幕阅读器能否响应“跳到主要内容”快捷键(如 JAWS 的 Insert+PageDown)。常见错误包括:
-
main被包在div里并加role="main"—— 旧版 VoiceOver 可能忽略该 role -
main出现两次,或被header/footer包裹 —— 浏览器可能丢弃节点,导致可访问性树断裂 - 用
section替代main—— 即使结构正确,也无法触发“主体内容”语义识别
label 绑定失效,键盘和语音用户同时卡住
label 不是让文字变可点击的 CSS 技巧,而是表单无障碍的最小运行时契约。一旦绑定失败:
- 屏幕阅读器 tab 到
input时只报“编辑文本”,不读用途(如“邮箱地址”) - checkbox/radio 点击文字无反应 —— 原生状态切换(Space/Enter)只在语义绑定成立时激活
- 错误提示无法与输入框关联,
aria-describedby失效
可靠写法只有 for/id 显式匹配:确保 input 有唯一非空 id,label 的 for 值与之**完全一致**(大小写、下划线、空格都算错),且无 pointer-events: none 遮挡点击区域。
语义化不是“锦上添花”,是可访问性树的原材料
浏览器生成可访问性树时,优先信任原生语义标签的隐式行为,而非人工拼凑的 ARIA。一个 nav 标签背后是焦点管理、键盘导航、状态同步、快捷键注册的整套契约;而 div role="navigation" 只是告诉读屏器“这看起来像导航”,其余全靠开发者自己补——稍有疏漏,用户就掉进无声的迷宫。真正容易被忽略的,是这些标签不是装饰,它们是运行时基础设施。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











