必须为div role="heading"显式添加aria-level属性(值为1–6整数),否则屏幕阅读器无法识别标题层级,且该属性不影响文档大纲生成。

div role="heading"必须显式加aria-level,否则无效
单独写 <div role="heading"> 不会告诉屏幕阅读器这是几级标题。它只声明“这是一个标题”,但没说“是h2还是h4”。辅助技术会忽略或默认为 level 2,行为不可控。
<p>必须配 <code>aria-level 属性,且值为 1–6 的整数:
-
<div role="heading" aria-level="2">章节标题</div>→ 被读作“二级标题” -
<div role="heading" aria-level="4">小节说明</div>→ 被读作“四级标题” - 不写
aria-level,或写成aria-level="0"、aria-level="7",都属于非法值,会被完全忽略
为什么不能只靠role="heading"?
因为 role="heading" 是 ARIA 的“角色覆盖”,它不自带层级语义——这和原生 <h1></h1>–<h6></h6> 不同。<h3></h3> 天然对应 aria-level="3",而 div 没有这种隐含映射。
常见错误场景:
- 在 CMS 模板里用
<div role="heading"> 渲染动态标题,但忘了传 <code>aria-level→ 所有标题被读成同一级 - 把
aria-level写成字符串如aria-level="two"→ 浏览器不解析,值被丢弃 - 用 CSS 类名推断层级(如
class="title-lv2")却不写aria-level="2"→ 辅助技术看不到 - SEO 工具、Lighthouse、部分读屏快捷键(如 NVDA 的 H 键跳标题)可能完全跳过它
- 如果页面已有
<h1></h1>,又用<div role="heading" aria-level="1">,不会造成大纲冲突,但也不会提升结构可信度 <li>想被大纲识别?唯一办法是改用 <code><h1></h1>–<h6></h6>,而不是补aria-level - 确保每个
role="heading"都带合法aria-level - 避免在同一个逻辑区块内混用原生标题和
role="heading"—— 容易让大纲断裂或朗读重复 - 检查是否真需要绕开语义标签:比如旧版 Ant Design 的
<typography.title></typography.title>默认渲染为div,这时才需手动补aria-level
aria-level 不等于 HTML 标题层级,也不参与大纲生成
aria-level 只影响屏幕阅读器播报,**不会让这个 div 进入浏览器的文档大纲(outline)**。Chrome DevTools 的“Accessibility”面板里能看到它被识别为 heading,但“Document Outline”视图里依然找不到它。
这意味着:
真正该优先考虑的替代方案
除非你受限于框架/组件库无法输出语义化标题标签,否则直接用 <h2></h2>、<h3></h3> 更可靠。
如果必须用 div + role:
最常被忽略的一点:当你用 JS 动态插入这类标题时,aria-level 必须由代码实时计算并写入 DOM,不能靠 class 名或 data 属性“猜”。否则展开折叠后,朗读层级就乱了。











