css计数器通过精准控制计数器与dom结构的映射关系实现复杂自动编号,依赖选择器匹配和声明顺序,支持跨容器连续计数、多级嵌套(counters)、条件编号、跳过逻辑及多组并行命名隔离。

要用 CSS 计数器实现复杂自动编号,关键不是“绕开 DOM”,而是**精准控制计数器与 DOM 结构的映射关系**。它不依赖元素是否真实渲染、是否父子嵌套,而是靠 CSS 选择器匹配和声明顺序驱动——这正是它能处理 <ol></ol> 做不到的逻辑的核心。
跨容器连续计数
当编号需贯穿多个不相关的容器(比如多个 <section></section> 或穿插的 <aside></aside>),<ol></ol> 会断开。CSS 计数器则无视 DOM 位置:
- 在最外层(如
article或body)设counter-reset: step; - 对所有要编号的元素统一写
step-item { counter-increment: step; },无论它们散落在哪 - 用
step-item::before { content: counter(step) ". "; }输出
隐藏元素(display: none)不会中断计数,因为 counter-increment 在样式计算阶段就已触发,不依赖渲染结果。
多级嵌套编号(如 2.1.3)
不能只靠 counter() 拼接,必须用 counters() 并配合层级重置:
-
h2 { counter-reset: subsection; counter-increment: section; }—— 每个h2重置子级计数器,并自增一级 -
h3 { counter-increment: subsection; }—— 只增子级,不重置父级 h3::before { content: counters(section, ".") "." counters(subsection, "."); }
注意:counters() 的第一个参数是计数器名,第二个是分隔符(必须加引号),它会从当前元素向上逐层收集同名计数器的值,自动拼接,无需手动判断层级深度。
条件性编号与跳过逻辑
某些元素需要参与编号流但不显示数字(如标题行、分隔线),或需跳过编号(如被注释掉的步骤):
- 给不显示编号的元素加
counter-increment: step;但不写::before,它仍会推动计数,只是不输出 - 要完全跳过某元素(不增也不显),用
counter-increment: none; - 需重置为特定值(如某节开头强制为“3.1”),在该元素上写
counter-reset: subsection 0; counter-increment: section 2;(先重置子级,再让父级跳到 3)
命名隔离与多组并行编号
同一页面多个独立编号序列(如“注意事项 1/2/3”和“操作步骤 1/2/3”)互不干扰:
- 为每组起不同计数器名:
counter-reset: note;和counter-reset: step; - 或复用名字但在新容器重置:
.notes { counter-reset: item; }+.steps { counter-reset: item; },两个item计数器彼此隔离 - 错误做法:在每个列表项上写
counter-reset: item;,会导致全部从 1 开始,无法递增
计数器名区分大小写,且作用域由 counter-reset 所在元素及其后代决定,天然支持嵌套隔离。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











