counter-reset 单独使用仅初始化计数器,需配合 counter-increment 和 content: counter() 才能显示编号;嵌套编号用 counters(),注意计数器名区分大小写及作用域重置规则。

counter-reset 和 counter-increment 必须成对出现才能生效
单独写 counter-reset: section; 不会让任何内容显示编号,它只是初始化一个计数器变量;真正触发编号渲染的是 counter-increment + content: counter(...) 的组合。常见错误是只设了 reset 却忘了 increment,结果页面一片空白编号。
典型用法是:在父容器设 counter-reset(如 counter-reset: section;),在子元素上设 counter-increment: section;,再用 ::before 伪元素配合 content: counter(section); 插入数字。
-
counter-reset一般放在最外层容器(如<ol></ol>、<article></article>或自定义 wrapper) -
counter-increment放在要“触发计数”的每个目标元素上(如<h2></h2>、<li>) - 计数器名区分大小写,
section和Section是两个不同计数器
嵌套编号要用 counter() 的第二个参数指定样式
默认 counter(section) 输出阿拉伯数字,但嵌套结构(如 1.1、1.2、2.1)需要 counters() 函数——注意是复数形式。它会自动拼接各级计数器值,并用指定字符串分隔。
例如:content: counters(section, "."); 配合多级 counter-increment: section;,就能生成带点号的层级编号。关键点在于:父级和子级必须使用同一个计数器名,且子级的 counter-reset 不能覆盖父级同名计数器(否则会重置)。
- 一级标题:
h1 { counter-increment: section; }+h1::before { content: counter(section) ". "; } - 二级标题:
h2 { counter-increment: section; }+h2::before { content: counters(section, ".") " "; } - 如果 h2 内部还希望重置子计数器(如 2.1a、2.1b),需另起一个名:
counter-reset: subitem;+counter-increment: subitem;
counter-reset 可以设初始值,但 increment 才决定步长
counter-reset: section 0; 表示从 0 开始计数,而 counter-reset: section 5; 就是从 5 开始。但实际显示值由 counter-increment 控制:默认是 +1,也可写成 counter-increment: section 2; 实现每次加 2。
这个特性常用于跳过序号(如跳过“0”章)、或实现偶数编号列表。注意:如果某元素同时有多个 counter-increment(比如 counter-increment: a b;),它们会各自独立累加,互不影响。
- 从 100 开始:
counter-reset: section 99;(因为第一次 increment 后才显示) - 每次加 3:
counter-increment: section 3; - 重置并设初值只影响该作用域内首次 increment 的起点,不影响已存在的上级计数器
浏览器兼容性没问题,但不要在 inline 元素上依赖伪元素插入
counter-reset 和 counter-increment 自 IE8 起就支持,现代浏览器无顾虑。真正容易出问题的是 content 在某些 inline 元素(如 <span></span>、<a></a>)上的表现:部分旧版 Safari 或 Firefox 可能不渲染 ::before,或导致换行错位。
稳妥做法是把计数逻辑绑定到块级或可设置 display: block 的元素上。另外,计数器是 CSS 运行时计算的,无法被 JavaScript 直接读取——如果后续需要获取当前编号做逻辑判断,得用 JS 模拟或改用 data-* 属性维护。
- 推荐载体:
<h1></h1>、<li>、<div class="chapter"> <li>避免载体:<code><span></span>、<em></em>、<strong></strong>(除非显式设display: inline-block) - 调试技巧:临时加
border: 1px solid red;看伪元素是否正常生成
CSS 计数器本质是声明式状态机,它的“状态”只存在于渲染树中,没有 DOM 节点对应,也不参与事件流——这点在调试动态插入内容时最容易被忽略。











