用css计数器可实现多级自动编号:每层ol需设counter-reset: step,li设counter-increment: step,li::before用counters(step, ".") ". "生成“1.1”格式;漏写内层ol的counter-reset会导致编号重置为1。

怎么用 ol 实现带自动编号的多级步骤列表
HTML 原生 ol 支持嵌套,但默认只对顶层计数,子 ol 会重置为 1。要实现「1.1、1.2、2.1」这类连续层级编号,不能只靠 HTML,得靠 CSS 的 counter-reset 和 counter-increment 配合 ::before 生成内容。
关键点:外层 ol 用 type="1"(默认),每层嵌套都需独立声明计数器,并在 li::before 中用 counters() 拼接层级 —— 注意是 counters()(带 s),不是 counter()。
-
counter-reset: step放在ol上,初始化计数器 -
counter-increment: step放在li上,每次递增 -
content: counters(step, ".") ". "放在li::before,生成「1.1」「2.3」这类格式
为什么直接写 <ol><ol></ol></ol> 会导致子项从 1 开始?
浏览器默认把每个 ol 当作独立计数容器,子 ol 不继承父级计数状态。即使你手动加 start="2",也无法动态响应父级变化,维护成本高且易出错。
CSS 计数器才是可靠解法 —— 它按 DOM 树深度自动累积,不依赖 HTML 属性。但要注意:必须给每层 ol 显式设置 counter-reset,否则内层不会触发自己的计数器实例。
- 漏写
ol ol { counter-reset: step; }→ 子层编号全为 1 - 把
counter-increment写在ol而非li上 → 编号跳变或重复 - 用了
counter(step)而非counters(step, ".")→ 只显示最内层数字,如「1」「2」而非「1.1」「1.2」
counters() 的分隔符和样式怎么控制?
counters() 第二个参数是字符串分隔符,常用 "." 或 "–",但它**不支持空格或 HTML 实体**(比如 " " 会失效)。想加空格,得靠 content 后拼接,例如:content: counters(step, ".") ". "。
字体、颜色、宽度等样式全部由 li::before 控制,不影响主文本。如果步骤文字需要缩进对齐,建议给 li::before 设固定 width + display: inline-block,避免编号宽窄不一导致文字错位。
- 分隔符只能是纯字符串,
counters(step, " > ")会报错 - 编号后加句点需手动写进
content,如counters(step, ".") "." - 若某层不需要编号(如说明性子项),给对应
li加counter-increment: none
兼容性和实际使用中的边界情况
IE8+ 和所有现代浏览器都支持 counters(),但 Safari 早期版本(≤12.1)对嵌套过深的 counters() 渲染有延迟,建议层级不超过 4 级。另外,屏幕阅读器通常忽略 ::before 生成的内容,所以语义化仍要靠结构:用 aria-label 补充可访问性。
- 打印时部分旧版 Chrome 可能丢失
::before编号,加@media print重置样式更稳妥 - 用 JavaScript 动态增删
li时,CSS 计数器自动生效,无需手动更新 - 若步骤含交互元素(如折叠/展开),确保
display: none的li不影响计数 —— 它仍参与counter-increment,如需跳过,改用visibility: hidden或移除节点
ol 重置、给 li 递增、用 counters() 拼前缀。真正容易被忽略的是嵌套层级里每一层 ol 都得显式 reset,而不是只写一次。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











