<nav>标签是导航意图的语义声明者,仅用于标识全局性、重复性、主要跳转路径的链接集合,如顶部主导航、侧边目录、页脚快速入口;须含真实href链接、配aria-label、禁止单链接或混入按钮/表单。

nav 标签不是导航功能的实现者,而是导航意图的声明者——它不控制跳转、不触发路由、不自动高亮当前页,只告诉浏览器、搜索引擎和屏幕阅读器:“这一块是用户用来在页面或站点间主要移动的链接集合”。
什么时候必须用 nav 而不是 div
只有当一组链接满足「全局性、重复性、主要跳转路径」三个条件时,nav 才是语义正确的选择:
- 主导航栏(如页眉中的「首页|产品|定价|联系」)
- 侧边文档目录(含
#section1、#api-reference等锚点链接) - 页脚快速入口(如「隐私政策|服务条款|帮助中心」)
- 多语言切换链接(
href="en/"、href="zh/"),前提是真实跳转
反例:上一篇/下一篇、返回顶部、打印本页、分享到微博 —— 这些属于操作或辅助行为,不构成“主要导航路径”,硬套 nav 会稀释语义。
nav 里不能放什么
语义污染往往发生在内容混入。以下元素一旦出现,nav 的可访问性与 SEO 价值就实质性受损:
立即学习“前端免费学习笔记(深入)”;
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 非链接元素:logo 图片(应留在
header)、搜索form、登录button、主题切换开关 - 伪链接:
<a href="javascript:void(0)">关于</a>或<button onclick="goTo('about')">关于</button>—— 屏幕阅读器无法识别为可跳转目标 - 空链接:
<a href="#">产品</a>(无实际跳转目标)或 DOM 加载时尚未渲染出链接的 SPA 导航容器 - 单个链接:
<nav><a href="/">首页</a></nav>—— 不构成“集合”,会被辅助技术忽略
正确做法是把搜索框放进 <header> 或 <section role="search">,把登录按钮放在用户菜单区域,而非塞进 nav。
多个 nav 共存时怎么区分用途
一个页面可以有多个 nav,但必须用 aria-label 或 aria-labelledby 明确标识各自目的,否则屏幕阅读器只会重复读出“navigation”,用户无法分辨哪个是主菜单、哪个是页脚快捷方式:
- 主导航:
<nav aria-label="主导航">...</nav> - 页脚导航:
<nav aria-label="页脚导航">...</nav> - 面包屑不推荐用
nav,更适合<ol class="breadcrumb" aria-label="当前位置">
绝对禁止嵌套:<nav><nav>...</nav></nav> 是 HTML 规范明确不允许的;也别用 title 属性替代 aria-label,它对键盘和语音用户基本无效。
nav 的 DOM 结构与无障碍基础要求
仅写 <nav><ul><li><a href="/">首页</a></li></ul></nav> 还不够。要让辅助技术真正识别并可用,需满足三项硬性条件:
- 链接必须带有效
href,且指向真实可访问路径(href="/about"可,href="#"不可) - 必须提供无障碍标识:
aria-label或关联可见标题(如aria-labelledby="main-nav-title") - DOM 加载完成时,内部必须已有可访问链接节点 —— SPA 中不能等异步请求回来再渲染
ul/li,否则初始无障碍树为空
最常被忽略的是第三点:React/Vue 组件中 nav 初始为空、靠 useEffect 或 mounted 拉取菜单数据,会导致屏幕阅读器首次加载时直接跳过该区域,后续也无法重新索引。


















