HTML有序列表中禁止在<li>内直接嵌套<h1>–<h6>,否则浏览器会自动闭合标题标签导致DOM错乱、屏幕阅读器误读、SEO权重分散;正确做法是用<section>配合CSS计数器模拟序号,或用/<span>实现视觉效果。

HTML 有序列表里不能直接用 <li> 包标题语义标签
HTML 标准中,<li> 是纯内容容器,不支持嵌套 <h1>–<h6> 作为“标题”——浏览器会自动闭合未预期的标题标签,导致 DOM 结构错乱、屏幕阅读器误读、SEO 权重分散。你看到的“标题效果”,大概率是 CSS 强行样式覆盖,而非语义正确。
真正可行的两种方式:语义优先 or 视觉模拟
取决于你要的是可访问性/SEO 正确的结构,还是仅视觉上像带标题的条目:
- 如果每个条目确实代表一个独立小节(比如 FAQ 列表、步骤说明),应改用
<section>+<h3>+ 普通段落,外层不用<ol>—— 序号靠 CSScounter-reset和::before生成 - 如果只是想让
<li>里某段文字加粗变大、看起来像标题,就用<strong>或<span>配 CSS,别碰<h[1-6]> - 切勿在
<li>内写<h3>步骤一:准备材料</h3><p>需要螺丝刀和胶带...</p>—— 这会让 W3C 验证失败,且部分辅助技术跳过后续内容
CSS 计数器实现“带标题感”的有序列表(推荐)
用原生 HTML 语义 + CSS 补序号,兼顾结构与样式:
<section class="step-list">
<section>
<h3>准备工具</h3>
<p>螺丝刀、胶带、说明书...</p>
</section>
<section>
<h3>拆卸外壳</h3>
<p>拧下四颗十字螺丝...</p>
</section>
</section>
对应 CSS:
立即学习“前端免费学习笔记(深入)”;
.step-list {
counter-reset: step;
}
.step-list > section {
position: relative;
padding-left: 3em;
}
.step-list > section::before {
content: counters(step, ".") ". ";
counter-increment: step;
position: absolute;
left: 0;
font-weight: bold;
}
为什么不用 <ol> 套 <h3>?看这个实际后果
写成这样:
<ol> <li><h3>第一步</h3>先通电</li> <li><h3>第二步</h3>再开机</li> </ol>
浏览器解析后实际 DOM 相当于:
<ol> <li></li> </ol> <h3>第一步</h3> 通电 <ol> <li></li> </ol> <h3>第二步</h3> 再开机
序号丢失、语义断裂、打印样式错乱——这不是 bug,是规范强制行为。
真要保序号又需标题语义,就老实用 <section> + CSS 计数器。别省那几行代码,后期维护和无障碍支持的成本远高于初期多写十行 CSS。



















