html5原生标签如、已自带隐式aria角色,显式添加role="navigation"等属冗余操作,易触发landmark-is-unique等错误;多个必须用aria-label区分用途,如“主导航”“页脚链接”;role="region"仅作兜底,须配aria-label且禁用于;验证需通过devtools accessibility面板及nvda按d键实测。

HTML5原生语义标签(如<nav></nav>、<main></main>)已自带隐式ARIA地标角色,直接使用即可被屏幕阅读器识别为可跳转区域;手动添加role属性不仅不必要,还可能干扰旧版辅助技术解析。
为什么给<nav></nav>加role="navigation"是错的
浏览器和辅助技术会自动将<nav></nav>映射为role="navigation",这是HTML5规范强制要求的行为。显式重复声明属于冗余操作:
- 某些旧版NVDA或JAWS在遇到双重角色时会跳过该地标,或报“role mismatch”警告
- DevTools的Accessibility面板中仍显示
navigation,但DOM树层级混乱,不利于调试 - 团队新人容易误以为“加了role才生效”,进而对
<header></header>、<footer></footer>也照搬,形成连锁错误
多个<nav></nav>怎么让屏幕阅读器分清主次
一个页面可以有多个<nav></nav>,但默认都叫“导航”,用户无法区分用途。必须用aria-label提供唯一上下文:
-
<nav aria-label="主导航"></nav>:顶部横向菜单,通常含首页、产品、关于等链接 -
<nav aria-label="页脚链接"></nav>:放在<footer></footer>内,含隐私政策、条款、联系方式等 -
<nav aria-label="搜索建议"></nav>:仅当搜索框展开后动态插入的<nav></nav>,且需配合aria-expanded="true"与焦点管理
避免用aria-labelledby——它依赖ID存在且可见,而搜索建议这类临时DOM容易ID缺失或文本不可见。
role="region"什么情况下真该用
role="region"是兜底方案,只在既无合适HTML5标签、又确实需要被识别为独立导航目标时才启用:
- 必须搭配
aria-label或aria-labelledby,否则屏幕阅读器直接忽略该区域(不会出现在地标列表中) - 不能用于
<section></section>:它本身不带地标语义,强行加role="region"会产生无意义的“区域 1、区域 2…”播报 - 典型合法场景:
<div role="region" aria-label="实时股票行情">,其中内容由WebSocket持续更新,且无对应HTML5语义标签 <p>注意:<code>role="region"不传递任何功能语义,仅表示“这里值得单独跳转”,所以label必须准确反映用途,不能写“内容区块”或“信息区”这类空泛描述。检查地标是否生效的实操方法
别只信代码写得“看起来对”,要验证真实辅助技术行为:
- Chrome DevTools → Elements → 右键元素 → Accessibility → 查看“Landmarks”面板是否列出预期角色及label
- NVDA + Firefox:按
D键循环跳转地标,听播报是否清晰区分“主导航”“页脚链接” - 禁用CSS后浏览:确保
aria-label文本仍可见(避免用display: none隐藏label源元素)
最容易被忽略的是动态渲染区域——比如SPA路由切换后新挂载的
<nav></nav>,若没触发aria-label重置或焦点恢复,地标就“消失”了,必须用JS监听并补全。











