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

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



















