Skip to content

标题层级与文档大纲

基于 HTML Living Standard · 核于 2026-06

速查

  • 六级标题:<h1><h6><h1> 最高,逐级往下;用真实层级,别拿标题当「变大变粗」的样式开关
  • 别跳级:线性文档里 <h1> 后直接跳 <h3> 是不符合规范的(缺了 <h2>
  • 一页通常只放一个 <h1>,描述整页主题(类似 <title>);多个 <h1> 标准允许但不是最佳实践
  • ⚠️ 「文档大纲算法」从未被任何浏览器实现——别依赖「每个分区元素里都放一个 <h1>、由 section 自动降级」这套幻想
  • 现实建议:显式h1h6 表达层级,分区元素(section/article不会自动改变标题级别
  • 读屏用户靠「在标题间快速跳转」来速览页面,跳级会让他们困惑「中间那级哪去了」
  • 关闭子区段时可以回跳(<h4> 之后回到 <h3><h2>),这是合法的;只是别向下跳级
  • 规范现状:若文档有标题,大纲中至少应有一个 <h1>;相邻标题级别向下最多差 1 级

六级标题的本质

HTML 提供六级标题:<h1><h6><h1> 级别最高,<h6> 最低。它们的用法,web.dev 类比得很贴切:

「像在文字编辑器里用标题级别一样:<h1> 是主标题,<h2> 是子章节标题,<h3> 是子章节里的小节……避免跳级。」

有一条铁律必须先立住:

别用标题来把文字变粗变大,那是 CSS 的活。

标题级别表达的是结构层级,不是字号。需要某段文字看起来大而粗,用 CSS font-size / font-weight绝不要为了视觉效果去选 <h3> 而非 <h1>。反过来,该是二级标题的内容,也不要因为「<h2> 默认太大」就降级写成 <h4>

两条核心规则

规则一:别向下跳级

线性阅读时,标题级别要连续,不能从 <h1> 直接跳到 <h3>

html
<!-- ❌ 错误:缺了 h2 -->
<h1>一级标题</h1>
<h3>三级标题</h3>
<h4>四级标题</h4>

<!-- ✅ 正确:逐级递进 -->
<h1>一级标题</h1>
<h2>二级标题</h2>
<h3>三级标题</h3>

为什么这么严格?因为读屏用户的核心导航方式之一就是「在标题间跳转」,借此快速摸清全页结构。MDN 警告:

「跳过一级或多级标题会制造困惑——这样导航的人会纳闷『缺掉的那级标题去哪了』。」

需要补一句细节:向下不能跳级(h1h3 不行),但在收束一个子区段、回到上层时,是可以回跳的——从 <h4> 直接回到 <h3> 甚至 <h2> 完全合法:

html
<h1>甲虫</h1>
  <h2>词源</h2>
  <h2>演化</h2>
    <h3>古生代晚期</h3>
    <h3>侏罗纪</h3>
  <h2>外部形态</h2>
    <h3>头部</h3>
      <h4>口器</h4>
    <h3>胸部</h3>     <!-- 从 h4 回到 h3,合法 -->

规则二:一页通常一个 <h1>

MDN 的建议是:

「一个页面一般只该有一个 <h1>,用来描述整页内容(类似文档的 <title>)。」

标准允许一页有多个 <h1>(只要不嵌套),但 MDN 明确指出「这不被视为最佳实践」。把唯一的 <h1> 留给「这一整页讲什么」,其下的章节用 <h2> 起步,是最稳妥、对 SEO 和读屏都最友好的做法。

⚠️ 避坑史料:那个「从未存在」的文档大纲算法

这是本页最重要、也最容易让人栽跟头的一段历史。

曾经的设想

早期 HTML 规范里有一套迷人的设想叫「文档大纲算法」(document outline algorithm):浏览器会像文字处理器一样,根据分区元素的嵌套自动计算标题层级。在这套设想下,你可以在每个 <section> / <article> 里都用 <h1>,由嵌套深度自动把它「降级」成实际的二级、三级标题:

html
<!-- 曾经的设想:每层都用 h1,靠 section 嵌套自动降级 -->
<h1>顶级标题</h1>
<section>
  <h1>本该被算成 h2 的标题</h1>
  <section>
    <h1>本该被算成 h3 的标题</h1>
  </section>
</section>

残酷的现实

这套算法从未被任何浏览器真正实现。 MDN 把这句话钉死在 <h1><h6> 文档的警告里:

「在旧版 HTML 标准里,于嵌套的分区元素中嵌套多个 <h1> 是被允许的。然而这从来不是最佳实践,如今已属不符合规范(non-conforming)。」

这意味着上面那段「全用 <h1> + section 自动降级」的代码,在现实中的后果是:屏幕阅读器和搜索引擎看到的,就是一连串平级的一级标题,根本没有任何降级发生。结构信息全部丢失。社区里那篇著名的《There Is No Document Outline Algorithm》(Adrian Roselli)讲的就是这件事。

现实里到底怎么做

结论非常简单——老老实实用 h1h6 显式表达每一级

  • <section> / <article> 的嵌套不会自动改变其中标题的级别;
  • 你想让某个标题是「三级」,就<h3>,而不是「写 <h1> 指望它被降级」;
  • 跨过分区元素时,标题级别也要保持连续(外层 <h1>,里面 <article> 的标题就该是 <h2>)。
html
<!-- ✅ 现实正确写法:显式写出真实级别 -->
<main>
  <h1>苹果</h1>
  <article>
    <h2>红蛇果</h2>
    <p>……</p>
  </article>
  <article>
    <h2>Granny Smith</h2>
    <p>……</p>
  </article>
</main>

规范现在怎么说大纲

WHATWG 现行标准不再描述那套复杂的大纲算法,转而强调显式的标题级别,给出两条可操作的约束:

  1. 「如果文档有一个或多个标题,大纲中至少应有一个标题级别为 1(即至少一个 <h1>)。」
  2. 「每个跟在另一个标题之后的标题,其级别必须小于、等于、或最多比前一个大 1。」——这正是「不许向下跳级」的规范表述,同时也允许向上回跳任意级。

换句话说,标准已经和现实和解了:别幻想自动大纲,把层级一笔一画写清楚。

<hgroup> 与标题的关系

如果一个标题需要配一行副标题 / 标语,用 <hgroup> 把它和 <p> 包在一起——注意它只能含一个 <h1><h6>

html
<hgroup>
  <h1>科学怪人</h1>
  <p>又名:现代普罗米修斯</p>
</hgroup>

<hgroup> 本身不影响文档大纲,真正进入大纲的是里面那个唯一的标题;<p> 副标题不计入层级。<hgroup> 的语义历史变迁(曾经用来包多个标题)属于易错点,详见 易错语义

小结

标题这件事,剥掉历史包袱后其实只剩两句话:用真实级别、别向下跳级,以及一页一个 <h1>。「分区元素自动算大纲」是个从未落地的美梦,别为它写代码。

下一步

层级讲完了,下一页收拾三个最常被误用的「冷门」语义元素——新的 <search>、容易被滥用的 <address>、语义已经变了的 <hgroup>易错语义