导航必须用标签并配具体aria-label,如“主导航”;内部结构须用或而非;当前页链接需保留href并设aria-current="page";不得嵌套在语义断层容器中。

导航必须用
只写<nav></nav>标签,屏幕阅读器大概率读作“导航区域”然后跳过——它无法区分这是主导航、面包屑还是页脚快捷入口。多个<nav></nav>共存时,aria-label不是可选项,是硬性要求。
常见错误包括:aria-label="Navigation"(太泛)、aria-label="nav"(拼写不规范)、或完全省略。正确写法必须紧扣功能,例如:<nav aria-label="主导航"></nav>、<nav aria-label="面包屑导航"></nav>、<nav aria-label="页脚快捷链接"></nav>。英文界面统一用aria-label="Main navigation",避免"Breadcrumbs"等非标准变体。
导航内部结构必须用或
,不能用堆链接<ul></ul>和<ol></ol>不只是样式容器,它们自带“可计数、可顺序遍历”的语义,键盘用户按↓或↑能自然流转,读屏器会播报“第1项”“第2项”。而<div>套<code>@#@#@#@#@#@#@#@#@#@0再用JS拦截,或者干脆删掉href,都会导致键盘用户无法聚焦、读屏器跳过该节点。这不是“禁用”,而是“语义终点”。
正确做法:
- 保留真实href(哪怕指向当前URL)
- 加aria-current="page"(值只能是"page",不能是"true"或"active")
- 不要给整个<nav></nav>加aria-current,它只作用于单个<a></a>元素
- 禁用项(如灰掉的“下一页”)用<button disabled></button>或aria-disabled="true" + tabindex="-1",并同步视觉样式
导航不能嵌套在语义断层容器里
<nav></nav>被包在<table>、<code><ul></ul>或带role="group"的<div>中,会导致地标传播中断——浏览器可能直接丢弃该节点,读屏器根本识别不到。<p>必须确保:<br>
- <code><nav></nav>是的直接子元素,或至少不被语义受限标签包裹
- 内部至少有一个可聚焦元素:<a></a>、<button></button>,或带tabindex="0"的容器
- 多个<nav></nav>必须各自有具体aria-label,不能共用同一个值
- DevTools里看到<nav></nav>标签,不代表它被辅助技术识别为地标;真正起作用的是浏览器暴露给读屏器的role、name和level
<ul></ul>和<ol></ol>不只是样式容器,它们自带“可计数、可顺序遍历”的语义,键盘用户按↓或↑能自然流转,读屏器会播报“第1项”“第2项”。而<div>套<code>@#@#@#@#@#@#@#@#@#@0再用JS拦截,或者干脆删掉href,都会导致键盘用户无法聚焦、读屏器跳过该节点。这不是“禁用”,而是“语义终点”。
正确做法:
- 保留真实href(哪怕指向当前URL)
- 加aria-current="page"(值只能是"page",不能是"true"或"active")
- 不要给整个<nav></nav>加aria-current,它只作用于单个<a></a>元素
- 禁用项(如灰掉的“下一页”)用<button disabled></button>或aria-disabled="true" + tabindex="-1",并同步视觉样式
导航不能嵌套在语义断层容器里
<nav></nav>被包在<table>、<code><ul></ul>或带role="group"的<div>中,会导致地标传播中断——浏览器可能直接丢弃该节点,读屏器根本识别不到。<p>必须确保:<br>
- <code><nav></nav>是的直接子元素,或至少不被语义受限标签包裹
- 内部至少有一个可聚焦元素:<a></a>、<button></button>,或带tabindex="0"的容器
- 多个<nav></nav>必须各自有具体aria-label,不能共用同一个值
- DevTools里看到<nav></nav>标签,不代表它被辅助技术识别为地标;真正起作用的是浏览器暴露给读屏器的role、name和level











