` 元素在屏幕阅读器中等于“沉默”,因其是纯容器、无内置语义,不播报也不支持导航快捷键;正确做法是使用 标签并配合 aria-label 或 aria-labelledby` 明确标识导航区域,确保其作为唯一地标被识别和跳转。

为什么 `` 在屏幕阅读器里等于“沉默”
因为 `
` 是纯容器,没有内置语义,屏幕阅读器默认不播报它,也不提供导航快捷键(比如 NVDA 的 D 键跳 ``、H 键跳标题——但那是弱线索,不可靠)。它只朗读其中的文本,且不说明上下文。
常见错误现象:<div class="nav">首页</div> → 屏幕阅读器只读“首页”,用户不知道这是导航区,也无法用快捷键跳过整个导航栏。
- 正确写法必须用
<nav></nav>,它自带 role="navigation",无需手动加
- 多个
<nav></nav> 时,必须用 aria-label 或 aria-labelledby 区分,否则所有导航都叫“导航”
-
<main></main> 是强制性地标:一个页面只能有一个,且不能嵌套在 <header></header>、<footer></footer>、<nav></nav> 内
哪些标签能真正被屏幕阅读器识别为结构节点
不是所有 HTML5 标签都对辅助技术有效。只有具备明确隐含角色(role)、可计算名称(name)和合理状态(state)的标签,才会被识别为可导航节点。
实操建议:
-
<header></header>、<nav></nav>、<main></main>、<footer></footer>、<aside></aside>、<article></article>、<section></section> 这些标签会暴露为区域地标(landmark),支持快捷键跳转(如 VoiceOver 的 M 键进 <main></main>)
-
<section></section> 必须配 <h2></h2>–<h6></h6> 才生效;没标题的 <section></section> 在键盘导航中直接被跳过
-
<button></button> 自带焦点、空格/回车触发、disabled 状态自动禁用交互与朗读;而 <div role="button"> 需手动补全 <code>tabindex="0"、onkeydown、aria-disabled、焦点样式——漏一项,键盘用户就卡住
aria-label、aria-labelledby、aria-describedby 怎么选
三者都用于补充可访问性文本,但用途和触发时机完全不同,乱用反而破坏体验。
-
aria-label:仅当元素本身**无可见文本**时使用,例如纯图标按钮 <button aria-label="关闭"><i class="icon-x"></i></button>
-
aria-labelledby:指向页面中**已有可见文本**的 ID,复用内容,适合表单组合(如 <label id="search-label">搜索</label> + <input aria-labelledby="search-label">)
-
aria-describedby:指向辅助说明文本(如错误提示、格式要求),会在主内容后朗读,适合 <input aria-describedby="hint-id"> 配合 <div id="hint-id">请输入邮箱格式</div>
- 容易踩的坑:同时用
aria-label 和内部文本,会导致重复朗读;用 aria-labelledby 指向不存在的 ID,屏幕阅读器会静默跳过
标题层级断裂会让屏幕阅读器彻底迷失
标题不只是样式,它是文档大纲(outline)的骨架。屏幕阅读器靠它生成导航树,标题层级断裂是最常被忽略的硬伤。
- 全页只允许一个
<h1></h1>(代表页面主主题),其余按逻辑嵌套递进
- 避免从
<h2></h2> 开始,或在 <main></main> 外堆三个 <h1></h1>;CSS 隐藏了 <h1></h1> 却没加 aria-hidden="true",会造成视觉与语音双重混乱
- 用
<h2></h2> 分割主要板块(如“产品介绍”“客户评价”),<h3></h3> 描述板块内子模块
- 检查 DOM 中每个标题是否被辅助技术正确识别——可用浏览器 DevTools 的 Accessibility 面板查看 computed role 和 name
最常被忽略的一点:语义标签的价值不在 HTML 源码里多写了几个单词,而在于它让标题结构、焦点顺序、样式作用域三者保持一致。
因为 `
常见错误现象:<div class="nav">首页</div> → 屏幕阅读器只读“首页”,用户不知道这是导航区,也无法用快捷键跳过整个导航栏。
- 正确写法必须用
<nav></nav>,它自带role="navigation",无需手动加 - 多个
<nav></nav>时,必须用aria-label或aria-labelledby区分,否则所有导航都叫“导航” -
<main></main>是强制性地标:一个页面只能有一个,且不能嵌套在<header></header>、<footer></footer>、<nav></nav>内
哪些标签能真正被屏幕阅读器识别为结构节点
不是所有 HTML5 标签都对辅助技术有效。只有具备明确隐含角色(role)、可计算名称(name)和合理状态(state)的标签,才会被识别为可导航节点。
实操建议:
-
<header></header>、<nav></nav>、<main></main>、<footer></footer>、<aside></aside>、<article></article>、<section></section>这些标签会暴露为区域地标(landmark),支持快捷键跳转(如 VoiceOver 的 M 键进<main></main>) -
<section></section>必须配<h2></h2>–<h6></h6>才生效;没标题的<section></section>在键盘导航中直接被跳过 -
<button></button>自带焦点、空格/回车触发、disabled状态自动禁用交互与朗读;而<div role="button"> 需手动补全 <code>tabindex="0"、onkeydown、aria-disabled、焦点样式——漏一项,键盘用户就卡住aria-label、aria-labelledby、aria-describedby怎么选三者都用于补充可访问性文本,但用途和触发时机完全不同,乱用反而破坏体验。
-
aria-label:仅当元素本身**无可见文本**时使用,例如纯图标按钮<button aria-label="关闭"><i class="icon-x"></i></button> -
aria-labelledby:指向页面中**已有可见文本**的 ID,复用内容,适合表单组合(如<label id="search-label">搜索</label>+<input aria-labelledby="search-label">) -
aria-describedby:指向辅助说明文本(如错误提示、格式要求),会在主内容后朗读,适合<input aria-describedby="hint-id">配合<div id="hint-id">请输入邮箱格式</div> - 容易踩的坑:同时用
aria-label和内部文本,会导致重复朗读;用aria-labelledby指向不存在的 ID,屏幕阅读器会静默跳过
标题层级断裂会让屏幕阅读器彻底迷失
标题不只是样式,它是文档大纲(outline)的骨架。屏幕阅读器靠它生成导航树,标题层级断裂是最常被忽略的硬伤。
- 全页只允许一个
<h1></h1>(代表页面主主题),其余按逻辑嵌套递进 - 避免从
<h2></h2>开始,或在<main></main>外堆三个<h1></h1>;CSS 隐藏了<h1></h1>却没加aria-hidden="true",会造成视觉与语音双重混乱 - 用
<h2></h2>分割主要板块(如“产品介绍”“客户评价”),<h3></h3>描述板块内子模块 - 检查 DOM 中每个标题是否被辅助技术正确识别——可用浏览器 DevTools 的 Accessibility 面板查看 computed role 和 name
最常被忽略的一点:语义标签的价值不在 HTML 源码里多写了几个单词,而在于它让标题结构、焦点顺序、样式作用域三者保持一致。
-











