必须用CSS计数器手动控制:外层ol设counter-reset: section,子ol设counter-reset: subsection,li用counter-increment递增对应计数器,并通过counters(section, ".")实现“1.1”“2.1”等嵌套编号。

ol嵌套时编号自动断层?用CSS counter-reset解决
默认情况下,ol嵌套后子列表会从1重新开始,但不会继承父级编号(比如“2.1”“2.2”)。这不是bug,是HTML规范行为——浏览器只对每个ol单独计数。要实现“1.1”“1.2”“2.1”这种效果,必须用CSS计数器手动控制。
- 给外层
ol设counter-reset: section,初始化计数器 - 每个
li用counter-increment: section累加 - 子
ol里再设counter-reset: subsection,并让子li同时递增两个计数器 - 用
::before拼接内容:counter(section) "." counter(subsection)
<ol>
<li>第一项
<ol>
<li>子项一</li>
<li>子项二</li>
</ol>
</li>
<li>第二项
<ol>
<li>子项三</li>
</ol>
</li>
</ol>
对应CSS:
ol { counter-reset: section; }
li { counter-increment: section; }
li::before { content: counters(section, ".") ". "; }
<p>ol ol { counter-reset: subsection; }
ol ol li { counter-increment: subsection; }
ol ol li::before { content: counters(section, ".") "." counters(subsection, ".") ". "; }</p>为什么不能只靠type属性或start?
type(如type="A")和start只影响单层显示格式与起始值,完全不处理嵌套逻辑。它们对子ol无继承性,也无法拼接父子编号。试图用start="2"硬调子列表起始值,会导致后续编号错乱,且无法响应父级变化。
-
type仅控制数字/字母/罗马符号样式,不参与计数逻辑 -
start是静态整数,不能绑定父级当前值 - 多级场景下,纯HTML属性无法表达“父编号 + 点 + 子编号”这种动态结构
兼容性与常见踩坑点
现代浏览器都支持counters()函数(注意是复数形式),但IE11及更早版本不支持嵌套计数器(counters(section, ".")会失效)。若需兼容IE,得退回到JavaScript生成编号或用伪元素+data属性模拟。
立即学习“前端免费学习笔记(深入)”;
- 忘记给子
ol重置子计数器(counter-reset: subsection),会导致子编号持续累加而非每组重来 - 在
li::before里误写counter(section)(单数)代替counters(section, "."),结果只显示最内层数字 - 把
counter-increment写在ol上而不是li上,编号不会随每个列表项递增
多级编号真正麻烦的不是写法,而是当列表结构动态变化(比如JS插入/删除li)时,CSS计数器仍能自动同步——这点反而比手写JS可靠。但一旦混用reversed或start属性,计数器行为就容易失控。



















