标签仅应用于承载页面级跳转链接的容器,如主导航、页脚链接或文章目录;多个必须用aria-label区分;内部推荐结构,需有有效href,避免滥用和可访问性缺陷。

nav 标签不是必须的,但用了就得真有用
浏览器和屏幕阅读器确实会把 <nav></nav> 当作导航区域识别,但前提是它里面真装了导航链接。如果只是用 <nav></nav> 包了一堆按钮、搜索框或广告位,反而会让辅助技术困惑——它以为这是主要导航,结果点进去啥也跳不到。
常见错误现象:role="navigation" 和 <nav></nav> 混用;<nav></nav> 套着整个页眉(含 logo、登录入口);一个页面塞 5 个 <nav></nav> 却没加 aria-label 区分。
- 只在承载「页面级跳转链接」的容器上用
<nav></nav>,比如主导航、页脚快捷链接、文章内目录 - 多个
<nav></nav>必须加aria-label或aria-labelledby,例如<nav aria-label="主导航"></nav> - 不要为了“语义化”而套壳——
<nav><div>...</div></nav>不如直接<nav><ul>...</ul></nav>
nav 里面该放什么 HTML 结构
<nav></nav> 本身不规定内部结构,但可访问性和样式维护强依赖合理嵌套。最稳妥的组合是 <nav></nav> + <ul></ul> + <li> + <a></a>,既符合习惯,也适配键盘 Tab 导航和屏幕阅读器列表播报逻辑。
使用场景:主导航菜单、面包屑、分页控件、侧边栏目录。注意分页控件用 <nav aria-label="分页"></nav> 是推荐做法,但面包屑更常用 <ol></ol> 而非 <ul></ul>(因有明确顺序)。
立即学习“前端免费学习笔记(深入)”;
-
<a></a>必须带有效href,空链接(href="#")或javascript:void(0)会破坏可访问性 - 下拉菜单需用
<ul></ul>嵌套,且父级<a></a>要加aria-haspopup="true"和aria-expanded - 避免在
<nav></nav>里塞表单控件(如搜索框),除非它是导航核心功能(如文档站的搜索跳转)
CSS 布局时 nav 的常见坑
<nav></nav> 默认是块级元素,但它的盒模型行为和其他块级标签没区别——别指望它自动“居中”或“横排”。很多初学者写完 <nav><a>首页</a><a>关于</a></nav> 发现链接竖着排,就以为是 <nav></nav> 的问题,其实是 <a></a> 默认 inline,没设 display 或 flex。
性能影响很小,但兼容性要注意:IE8 及以下不识别 <nav></nav>,会当普通 <div> 渲染,所以语义化收益为零;不过加个 <code>document.createElement("nav") 就能 hack 支持(现代项目基本不用管)。
- 横向排列优先用
display: flex,比float或inline-block更可控 - 移动端响应式时,别只靠
display: none隐藏<nav></nav>,记得同步处理aria-hidden和焦点管理 - 如果用 CSS Grid 布局,
<nav></nav>可以直接设为grid-area,但别让它撑满整行又留白——视觉和语义要一致
用 JS 操作 nav 时容易忽略的细节
动态生成导航(比如从 JSON 渲染菜单)时,很多人只管追加 <a></a>,却忘了补全可访问性属性。键盘用户按 Tab 进入 <nav></nav> 后,如果子项没有正确 focusable 状态或角色,就会卡住。
错误现象:document.querySelector("nav").innerHTML = "<a>首页</a>" 后,链接无法被键盘聚焦(因为没 tabindex,且 href 缺失);点击下拉后,子菜单没加 aria-hidden="true/false",屏幕阅读器仍会读出隐藏项。
- 动态插入链接前,确保每个
<a></a>有合法href,禁用状态用aria-disabled="true"+tabindex="-1" - 展开/收起菜单时,同步切换
aria-expanded和aria-hidden,并用focus()把焦点移到第一个可操作子项 - 监听
keydown实现方向键导航时,只在<nav></nav>内部处理,避免和页面其他快捷键冲突
<nav></nav>,而是每次加新链接时,都记得它背后连着键盘、屏幕阅读器和搜索引擎的判断逻辑。



















