<nav>标签仅用于主要导航区块,须配aria-label或aria-labelledby,内部宜用<ul><li>结构,避免语义滥用与隐藏失效。

nav 标签不是“必须包住所有链接”的容器
<nav> 是语义化标签,表示页面中**主要的导航区块**,不是装饰性容器。浏览器、屏幕阅读器和搜索引擎靠它识别“这是导航区”,但不会自动添加样式或交互逻辑。
常见错误是把所有带链接的区域都套上 <nav>,比如页脚友情链接、文章内“上一篇/下一篇”、侧边栏分类列表——这些通常不属于主导航,用 <div> 或更合适的 <aside> / <footer> 更准确。
- 主导航:顶部横向菜单、左侧垂直菜单、移动端汉堡菜单弹出层 → 适合用
<nav> - 次要链接集合(如“相关文章”“合作伙伴”)→ 不要用
<nav>,避免语义污染 - 一个页面可以有多个
<nav>,但需有明确区分,例如:<nav aria-label="主导航">和<nav aria-label="面包屑导航">
必须配 aria-label 或 aria-labelledby 才算合格
仅写 <nav><a href="/home">首页</a></nav> 是不完整的。辅助技术无法知道这个导航叫什么、用途是什么。WAI-ARIA 要求为每个 <nav> 提供可识别的名称。
推荐优先使用 aria-label,简洁直接:
立即学习“前端免费学习笔记(深入)”;
<nav aria-label="主导航"> <a href="/home">首页</a> <a href="/about">关于</a> <a href="/contact">联系</a> </nav>
如果导航标题已存在(比如 <h2>网站导航</h2>),可用 aria-labelledby 关联:
<h2 id="main-nav-title">网站导航</h2> <nav aria-labelledby="main-nav-title"> <a href="/home">首页</a> <a href="/products">产品</a> </nav>
- 不写
aria-label或aria-labelledby→ 屏幕阅读器可能读作“导航”,无上下文,体验断裂 - 避免用空字符串
aria-label="",这会让部分读屏器跳过整个<nav> - 不要依赖 CSS 隐藏的文本(如
visually-hiddenclass)作为唯一标识,仍需显式 ARIA 命名
nav 内部结构要扁平,别嵌套 div 或 ul 当“布局工具”
<nav> 本身不规定内部结构,但语义最佳实践是:用 <ul> + <li> 组织链接列表,既符合习惯,也利于无障碍遍历(读屏器默认将 <ul> 识别为“列表”,告知用户共几项)。
错误写法(纯 div 布局,无结构提示):
<nav aria-label="主导航"> <div class="nav-item"><a href="/home">首页</a></div> <div class="nav-item"><a href="/blog">博客</a></div> </nav>
正确写法(语义清晰、可访问性强):
<nav aria-label="主导航">
<ul>
<li><a href="/home">首页</a></li>
<li><a href="/blog">博客</a></li>
<li><a href="/archive">归档</a></li>
</ul>
</nav>
- 不用
<ol>,除非导航项有严格顺序依赖(极少见) - 避免在
<nav>里塞<section>、<article>等无关语义容器 - 下拉菜单需额外处理焦点流和
aria-haspopup/aria-expanded,不能只靠 HTML 结构
响应式导航切换时,nav 的可见性与语义不能断开
移动端常把导航收进“汉堡菜单”,用 JS 控制 display: none 或 visibility: hidden。这时要注意:隐藏不等于销毁,<nav> 仍需保持语义有效。
- 用
display: none→ 整个<nav>从渲染树和无障碍树中移除,屏幕阅读器完全感知不到 —— 错误 - 用
visibility: hidden或opacity: 0→ 元素仍在无障碍树中,但视觉不可见,易造成混淆 —— 不推荐 - 正确做法:用
clip-path或position: absolute; left: -9999px;隐藏,同时确保aria-hidden="false"(默认值)且未被 JS 错误设为true - JS 展开后,记得把焦点移到第一个导航项:
nav.querySelector('a').focus()
复杂点在于:很多人以为“nav 只要存在就行”,却忽略了 JS 控制显隐时对无障碍状态的破坏。实际项目中,90% 的可访问性问题出在这里,而不是标签写没写对。











