nav标签是承载真实主导航意图的语义容器,必须包裹至少两个有效href链接,禁用按钮表单等非导航内容,多nav须用aria-label明确区分用途,推荐ul/li结构以保障可访问性。

nav 标签不是“加了就语义正确”的装饰,而是必须承载真实主导航意图的语义容器;用错比不用更糟。
nav 必须直接包裹跳转链接,不能混入按钮或表单
浏览器和屏幕阅读器看到 <nav></nav>,会默认这里是一组用于页面级跳转的链接。如果里面塞了 <button></button>、<input> 或纯文本说明,辅助技术会困惑——它以为能导航,结果点进去没跳转。
- ✅ 正确:
<nav><ul><li><a href="/products">产品</a></li></ul></nav> - ❌ 错误:
<nav><button onclick="toggleMenu()">☰</button></nav>(按钮不是导航目标) - ❌ 错误:
<nav><form><input name="q"></form></nav>(搜索框不属于导航语义) - ⚠️ 边界情况:面包屑通常用
<ol class="breadcrumb"></ol>,不套<nav></nav>,因为它是位置路径,不是跳转入口集合
多个 nav 必须用 aria-label 区分用途
一个页面可以有多个 <nav></nav>,比如顶部主菜单、页脚快捷链接、文章内目录锚点。但如果不加 aria-label,屏幕阅读器用户按 NVDA+Insert+N 跳转时,只会听到重复的 “navigation”,无法分辨哪一个是“主导航”、哪一个是“页脚工具栏”。
- ✅ 推荐:
<nav aria-label="主导航">...</nav>、<nav aria-label="页脚快捷导航">...</nav> - ✅ 如果导航上方已有可见标题(如
<h2 id="toc-title">目录</h2>),可用aria-labelledby="toc-title"复用文本,避免维护两套文案 - ❌ 避免:
aria-label="menu"或留空——对用户毫无信息量 - ❌ 不要同时写
role="navigation"——<nav></nav>已隐含该 role,冗余声明可能干扰旧版读屏
内部结构推荐 ul + li + a,不是为了样式,而是为了可访问性
<nav></nav> 本身不强制结构,但屏幕阅读器依赖列表语义来播报导航项。平铺 <a></a> 或用 <div> 模拟菜单项,会导致连读成一长串无停顿文本,键盘 Tab 焦点也无法自然分组管理。<p><span>立即学习</span>“<a href="https://pan.quark.cn/s/cb6835dc7db1" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">前端免费学习笔记(深入)</a>”;</p>
<ul>
<li>✅ 推荐结构:<code><nav aria-label="主导航"><ul>
<li><a href="/">首页</a></li>
<li><a href="/about">关于</a></li>
</ul></nav>
<nav aria-label="主导航"><a href="/">首页</a> <a href="/about">关于</a></nav>,但 Lighthouse 可能报「导航缺少列表结构」<nav><div><a href="/">首页</a></div>
<div><a href="/about">关于</a></div></nav>(<div> 无列表语义,AT 无法识别为可导航项)
<li>⚠️ 注意:<code><ul></ul> 的语义价值不在于视觉样式,哪怕你用 CSS 清掉所有默认 margin/padding/list-style,它依然起作用nav 不该嵌套在 header 里?这个说法是错的
网上有说法称 “<nav></nav> 必须直接位于 下,不能放在 <header></header> 里”,这是对 HTML5 规范的误读。<header></header> 本就是 sectioning content,天然支持包含 <nav></nav>,且实际项目中绝大多数主导航都位于 <header></header> 内部。
- ✅ 正确且常见:
<header><h1>网站名</h1> <nav aria-label="主导航">...</nav></header> - ❌ 错误做法:
<div class="header"><nav>...</nav></div>(<div> 不提供任何语义,<code><nav></nav>失去上下文) - ⚠️ 真正要避免的是语义嵌套冗余,比如
<header><nav><nav>...</nav></nav></header>—— 一层<nav></nav>就够,多套一层反而稀释语义 - ? 开发者工具中,
<nav></nav>会被归类为 Landmark,只要结构合理,无论在<header></header>内还是<main></main>旁,都能被无障碍工具正常识别
最难的部分从来不是怎么写 <nav></nav>,而是判断哪些链接集合,在用户真实浏览路径中构成了“导航”——这得看点击流、跳失率和辅助技术用户的反馈,而不是看代码缩进是否整齐。



















