必须使用原生<h1>至<h6>标签定义标题,role="heading"因缺乏大纲支持、样式继承和键盘导航等能力而不可靠,仅在无法修改HTML结构的极端场景下配合aria-level谨慎使用。

role="heading" 不是替代 – 的正确方式
的正确方式
浏览器和屏幕阅读器对 role="heading" 的支持非常有限,它不会自动产生标题层级语义、不参与文档大纲(outline)、也不触发默认的样式或键盘导航行为。真正定义标题,必须用原生 <h1> 到 <h6> 标签。
什么时候会看到 role="heading"?常见错误场景
多数出现在以下情况,本质是语义误用:
- 用
<div role="heading">试图“模拟”标题,但没加aria-level - 第三方 UI 库(如旧版 Ant Design 或自研组件)未正确透传 heading 层级,只硬编码
role="heading" - 开发者误以为加了
role就能绕过 HTML 结构约束,比如在<span>上加role="heading"
这类写法在 Chrome DevTools 的 Accessibility 面板里可能显示为 heading,但 NVDA/JAWS 实际朗读时往往跳过,或统一读成“标题”,不带级别信息。
如果真要用 role="heading",必须配 aria-level
role="heading" 单独存在是无效的。它依赖 aria-level 显式声明层级,否则辅助技术无法判断这是 h2 还是 h4:
立即学习“前端免费学习笔记(深入)”;
<div role="heading" aria-level="2">二级标题内容</div>
但注意:
-
aria-level值必须是 1–6 的整数,超出范围会被忽略 - 即使写了
aria-level="1",也不会让这个<div>在浏览器大纲中排第一(<h1>才会) - CSS 中
h2默认的font-size和margin不会自动应用到该<div>,需手动补全
真正需要语义化标题时,只用原生 heading 标签
除非极特殊场景(例如动态渲染且无法改 HTML 结构的遗留系统),否则不要用 role="heading"。直接写:
<h2>这个才是可靠标题</h2>
好处是:
- 天然进入 document outline,被所有辅助技术识别
- 支持原生键盘导航(如 Windows 下 NVDA + Insert+T 跳标题)
- 搜索引擎明确理解语义权重
- 无需额外 ARIA 属性,代码更轻、更健壮
如果你正在封装一个标题组件,内部应该渲染 <h1>–<h6>,而不是用 div + role —— 层级由 props 决定标签名,不是靠 ARIA 模拟。



















