<nav>比<div role="navigation">更安全,因其是原生语义标签,自带隐式role="navigation"且默认可聚焦、可跳转;手动添加role反而可能触发校验错误,且多个<nav>必须用aria-label区分功能,否则屏幕阅读器无法识别上下文。

为什么用 <nav> 比写 <div role="navigation"> 更安全
因为 <nav> 是原生语义标签,浏览器和屏幕阅读器默认就把它识别为导航区域,role="navigation" 是它的隐式角色,不需要、也不该显式声明。一旦你手动加了 role="navigation",反而可能触发 landmark-is-unique 或 landmark-no-label 等可访问性校验错误。
常见错误现象:
- 多个
<nav>都没加aria-label或aria-labelledby→ 屏幕阅读器全读成“导航区域”,用户无法区分主导航、页脚链接、面包屑 - 用
<div role="main">替代<main>→ 必须确保全局唯一,否则 Lighthouse 和 axe 会报错 - 给
<section>加role="region"却漏掉aria-label→ 直接触发landmark-no-label
<caption> 必须紧贴 <table> 开头,不能放错位置
<caption> 是表格唯一的语义化标题标签,不是装饰性元素。它必须作为 <table> 的第一个子元素出现,否则会被辅助技术忽略——既不朗读,也不参与结构树构建。
容易踩的坑:
立即学习“前端免费学习笔记(深入)”;
- 把
<caption>塞进<thead>或<tbody>里 → 语义失效,屏幕阅读器跳过 - 沿用已废弃的
summary属性 → 所有现代读屏器都不支持,Chrome DevTools Accessibility Inspector 里直接显示为空 - 写空
<caption></caption>→ 触发caption-missing错误,且对视障用户毫无信息价值
<main> 只能出现一次,且不能嵌套在 <article> 或 <section> 内
<main> 表示页面唯一核心内容区域,它的语义是全局唯一的。W3C 明确规定它不得嵌套在其他地标容器中,否则会破坏辅助技术对页面主干内容的定位逻辑。
典型误用场景:
- 在某个
<article>里再包一层<main>→ 导致多个mainlandmark,违反landmark-is-unique规则 - 用
<div class="main-content">+role="main"模拟 → 多余且风险高,role="main"必须确保唯一,而人工维护极易出错 - 把
<main>放在<header>或<footer>同级但被包裹在<div>中 → 若该<div>被设为display: none,<main>的Computed Role会变成generic,而非main
Chrome DevTools Accessibility Inspector 怎么快速验证地标是否生效
不用装插件、不跑 CLI,Chrome 自带工具就能实时看语义是否被正确解析。打开方式:Mac 按 Cmd+Shift+P,Win/Linux 按 Ctrl+Shift+P,输入 “Accessibility” 回车;或右键任意元素 → Inspect Accessibility Properties。
重点盯三列:
-
Computed Role:确认是否为预期值(如<nav>应显示navigation,若显示generic,说明被 CSS 隐藏了) -
Name:为空即触发landmark-no-label,尤其是多个<nav>或<aside>必须靠aria-label或aria-labelledby区分 -
States:比如expanded是否同步更新,这对含折叠逻辑的<details>或自定义菜单很关键
最常被忽略的一点:即使代码写了 <nav>,如果它父容器用了 visibility: hidden 或 display: none,它的 Computed Role 就会降级为 generic —— 语义完全丢失,但 HTML 结构看起来完全正常。



















