多个<nav>必须用不同aria-label值,不能重复或泛化;如主导航、页脚导航、管理面板等需语义明确区分,避免“导航”等泛称;优先用aria-label写死静态文案,动态场景用aria-labelledby引用可见标题,二者不可混用。

多个
页面里出现两个以上 <nav> 时,aria-label 不是可选项,而是强制要求。屏幕阅读器不会自动识别“哪个是顶部菜单”“哪个是页脚链接”,全靠你写的文本区分。写成 aria-label="Navigation" 或 aria-label="导航" 等泛称,等于没写——NVDA、VoiceOver 会连续报出“导航区域”“导航区域”,用户无法判断上下文。
-
aria-label="主导航":用于页眉横向主菜单,含首页、产品、博客等核心跳转入口 -
aria-label="页脚导航":专指页脚的“隐私政策”“联系我们”“合作伙伴”等站点级辅助链接 -
aria-label="管理面板":后台系统中左侧垂直菜单,与前台逻辑隔离,需独立语义 - 避免
aria-label="菜单"、aria-label="顶部导航"这类带位置描述但无业务含义的写法——视觉位置可能随响应式变化,而语义必须稳定
aria-label 和 aria-labelledby 怎么选
两者都能实现区分,但适用场景不同:aria-label 是直接写死文本,aria-labelledby 是引用已有可见标题的 ID。后者更适合多语言站点或动态文案场景,比如导航上方有个 <h2 id="admin-nav">系统管理</h2>,就可以写 <nav aria-labelledby="admin-nav">。
- 静态、固定文案(如“主导航”)→ 优先用
aria-label,简洁可控 - 已有可见标题且内容可能变化(如后台模块名由 CMS 动态生成)→ 用
aria-labelledby,避免文案重复维护 - 不要混用:同一个
<nav>上同时写aria-label和aria-labelledby,后者会覆盖前者,且易引发不可预期读屏行为
哪些地方不该用
<nav> 不是样式容器,它代表的是“全局性、主要的跳转入口集合”。塞错内容不仅无效,还会误导辅助技术。
-
<nav><button>首页</button></nav>—— 按钮不是可跳转链接,违反<nav>的语义前提 - 文章内锚点列表(如“本文目录”)→ 应用
<div role="navigation">,而非<nav> - 面包屑导航 → 更推荐
<ol class="breadcrumb">+aria-label="当前位置",语义更精准;若硬要用<nav>,必须配aria-label="面包屑导航",且不能和主导航混用 - 搜索框、登录按钮、广告位 → 全部剔除,它们不属于导航范畴
动态插入的导航也要保证 DOM 就绪时有有效链接
单页应用中用 JS 渲染导航,容易忽略最终 DOM 状态。如果 <nav> 初始为空,或只渲染了占位符(如 loading 状态),读屏器会跳过或报错。必须确保用户能实际点击的 <a href> 在 DOM 中真实存在且可访问。
立即学习“前端免费学习笔记(深入)”;
- 服务端渲染或静态 HTML:检查源码中
<nav>内是否包含至少一个有效<a href="/xxx"> - 客户端渲染:在
useEffect或 DOM 更新后,用浏览器开发者工具的“Accessibility”面板验证<nav>是否被正确识别为“navigation”,且子节点含 link role - 禁用状态链接(
<a href="#" onclick="return false">)不算有效导航,应移除或改用<span>+aria-disabled="true"
<nav> 当成“视觉分组”来用,而不是按语义职责划分。只要记住一点:每个 <nav> 都得回答“用户为什么需要它”,答案就是它的 aria-label。



















