一个页面绝大多数场景下只能有一个h1,且须位于主干内容开头;html5虽允许多个h1但需严格限定在独立语义区块内,实际项目中95%应坚持全局唯一h1原则。

一个页面到底能用几个 h1?
绝大多数场景下,页面只能有一个 h1,且必须出现在主干内容开头附近。CMS 模板里轮播图、商品卡片、侧边栏模块如果各自硬塞一个 <h1>新品上市</h1>,搜索引擎和读屏器会彻底混乱——它们无法判断哪个才是真正的页面主题。
HTML5 允许在独立语义区块(如 <article></article> 或 <section></section>)内用 h1,但前提是:该区块有明确边界、可被 aria-labelledby 或 role="region" 精确识别,且整页大纲仍能被无障碍工具线性解析。实际项目中,95% 的页面应坚持“全局唯一 h1”原则。
h2 到 h6 必须严格嵌套,不能跳级
出现 <h1>React Hooks</h1>
<h4>useEffect 清理时机</h4> 这类写法,DevTools 的 Accessibility 面板会直接报 heading-level-skipped 错误。读屏器用户语音导航时,会从 h1 直接跳到 h4,中间的逻辑层完全“掉空”。
层级必须连续:
-
h1→h2→h3是合法路径 -
h1→h2→h2是合法同级并列 -
h1→h3或h2→h4是非法断裂
真需要更细粒度组织?优先考虑 <dl></dl>、<details></details> 或带语义 class 的 <div>,而不是强行塞进 <code>h4–h6。
动态渲染标题时,props.level 必须校验范围
Vue/React 中常见写法:<component :is="`h${level}`">内容</component>,但传入 level = 0、level = 7 或字符串 "2.5" 会导致输出非法标签(如 <h7></h7>),浏览器静默忽略,DOM 结构直接失效。
安全做法:
- 只接受
1–6的整数 - 非合规值统一 fallback 到
h2(比h1更稳妥,避免意外升权) - 服务端渲染首帧必须含有效
h1,不能依赖 JS 注入后才补 - 禁用
v-html或dangerouslySetInnerHTML拼接标题标签——一个拼写错误就破坏整个大纲
样式重置别只盯着字体大小
浏览器默认 h1–h6 的 margin 和 line-height 差异大,旧版 iOS Safari 对 h6 行高处理异常。建议起步就加基础重置:
h1, h2, h3, h4, h5, h6 {
margin: 0;
font-weight: normal;
line-height: 1.2;
}
真正关键的是:打开 DevTools 的 Accessibility 面板,右键检查节点,看它被识别为第几级 heading 元素。视觉上 h6 比 h1 还大也没关系,只要 DOM 层级没乱,机器就能读对。
复杂点在于,标题结构不是写完就完的事——它得经得起 SSR 首帧校验、JS 动态注入校验、无障碍扫描工具校验,三者缺一不可。最容易被忽略的,是 CMS 模板里那些“看起来没问题”的复用卡片,它们悄悄把 h1 塞进每个模块,最终让整页大纲崩成碎片。











