必须在父容器设counter-reset,子元素设同名counter-increment才能启动计数;用counter()函数在::before中输出序号,支持样式参数;嵌套用counters()自动拼接层级;list-style:none不影响自定义序号,但需确保::before和content存在。

counter-reset 和 counter-increment 怎么配对用
不声明 counter-reset,counter-increment 就没起点,序号永远是 0。必须在列表容器(比如 ol 或 ul)上设 counter-reset: my-counter,再在每个 li 上写 counter-increment: my-counter,才能让计数器逐项累加。
常见错误:把 counter-reset 写在 li 上——这会导致每项都重置为 0,结果全是 “1”。
-
counter-reset通常只设一次,在父容器上 -
counter-increment必须作用于要显示序号的每个子元素(如li::before) - 名称要一致:
counter-reset: section对应counter-increment: section,不能拼错或大小写混用
如何用 counter() 函数插入自定义序号样式
counter() 是唯一能读取计数器值并转成文本的函数,必须配合 ::before 伪元素使用。它支持两个参数:counter(name) 和 counter(name, style),其中 style 可选 decimal、lower-roman、upper-alpha 等。
比如想让序号带括号且小写罗马数字:content: counter(item, lower-roman) ". ",渲染出来就是 “i. ”、“ii. ”。
- 不能直接在
content外使用counter(),CSS 不允许在其他属性中调用 - 如果省略
style,默认是decimal(阿拉伯数字) - 多个计数器可嵌套:用
counters(name, separator)实现多级(如 “1.1”、“1.2”),但注意separator必须是字符串字面量,如"."
为什么 list-style: none 后序号消失了
因为浏览器原生序号(ol 的数字)和 counter() 生成的序号互不干扰。删掉 list-style 只是隐藏了原生序号,不影响你手动写的 counter();但如果忘了写 ::before 或漏了 content,就会“什么都没显示”——看起来像序号丢了,其实是没触发渲染。
- 务必检查
li::before { content: counter(...); }是否存在且生效 -
li::before默认是 inline,若需要对齐或间距,得显式设display: inline-block或调整margin-right - 如果用了
display: flex在li上,::before可能被挤出可视区,需加flex-shrink: 0或调整order
嵌套列表怎么让子级序号继承父级
靠 counters() 而不是 counter()。它会自动收集从根到当前元素的所有同名计数器,并用指定分隔符拼接。父容器设 counter-reset: section,子容器再设一次 counter-reset: subsection 并在子项上 counter-increment: subsection,就能实现 “1 → 1.1 → 1.1.1” 这类结构。
但更简单通用的做法是:所有层级共用一个计数器名,只靠 counters("section", ".") 自动处理嵌套深度——前提是 HTML 结构是真正嵌套的(li 里有 ol / ul)。
-
counters()的第二个参数必须是字符串,写成'.'或"."都行,但不能是变量或 CSS 变量 - 如果嵌套层级没在 DOM 中真实嵌套(比如用 JS 拼的扁平列表),
counters()就无法识别层级关系,得换用 JS 控制或额外 class 区分 - 计数器名区分大小写,
Section和section是两个独立计数器
最易忽略的一点:计数器作用域是“块容器”,不是“标签名”。哪怕你用 div 模拟列表,只要正确设置 counter-reset 和 counter-increment,一样能跑起来——关键在逻辑链是否闭合,不在语义标签。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











