nav标签仅为语义容器,需CSS实现样式与交互,且必须配合ARIA属性、键盘焦点管理及aria-label区分多导航区域才能保障可访问性。

nav 标签本身不渲染样式,必须配合 CSS 才能“看得见”
很多人写完 <nav><a href="/home">首页</a><a href="/about">关于</a></nav> 发现菜单还是堆成一列、没间距、没悬停效果——这不是 <nav> 的问题,它只是语义容器,浏览器不会自动加样式。
真正起作用的是 CSS:用 display: flex 水平排布、gap 控制间距、:hover 做交互反馈。
常见错误是只写 HTML,以为用了 <nav> 就等于做出了导航栏。
链接内部别嵌套 <div> 或 <p>,否则语义错乱且可能破坏可访问性
<nav> 里应直接放 <a>、<button> 或带 role="link" 的元素。嵌套块级标签会干扰屏幕阅读器识别导航项,也容易让 CSS 布局失控。
比如下面这种写法是错的:
<nav>
<a href="/home">
<div>首页</div> <!-- 不要这样 -->
</a>
</nav>正确做法是把样式逻辑交给 CSS,用 <a> 自身做容器:
<nav> <a href="/home" class="nav-link">首页</a> <a href="/about" class="nav-link">关于</a> </nav>
然后用 .nav-link { display: block; padding: 8px 16px; } 控制点击区域。
立即学习“前端免费学习笔记(深入)”;
移动端下拉菜单不能只靠 <nav>,得用 JavaScript 控制 aria-expanded 和显隐状态
响应式导航菜单(比如汉堡图标点开下拉)需要三要素同步:视觉显隐、键盘焦点管理、ARIA 状态标记。只用 CSS display: none 会让屏幕阅读器跳过整个菜单。
关键操作包括:
- 给触发按钮加
aria-expanded="false",点击后切换为"true" - 给下拉菜单容器加
aria-hidden="true",展开时设为"false" - JavaScript 展开后,用
focus()把键盘焦点移到第一个链接上 - 按
Esc键时收起菜单并还原所有 ARIA 属性
漏掉任意一项,都会让视障用户无法操作菜单。
多个导航区域要用 aria-label 区分,否则屏幕阅读器全念成“导航”
一个页面可能有顶部主导航、侧边栏辅助导航、页脚链接导航。如果都只写 <nav>,NVDA 或 VoiceOver 会全部读作“导航”,用户无法分辨哪个是哪个。
必须用 aria-label 明确说明用途:
<nav aria-label="主导航">...</nav> <nav aria-label="页脚资源链接">...</nav>
注意不要用 aria-labelledby 指向一个不可见的 <h2>,因为某些读屏软件对隐藏标题支持不稳定;aria-label 是更稳妥的选择。
实际项目里最常被忽略的是 ARIA 状态同步和移动端键盘焦点管理——视觉看起来没问题,但对依赖键盘或读屏器的用户来说,菜单根本不可用。



















