counter-reset 必须设在要开始新序列的容器上(如 .chapter { counter-reset: chapter; }),而非全局;它仅对直接子元素生效,需配合 counter-increment 和 content 中的 counter()/counters() 才可见编号。

counter-reset 怎么设才生效
它只对当前元素的直接子元素起作用,不是全局变量。很多人以为在 body 上设一次就能全页面计数,结果发现 h2 没重置、li 还接着上一个数——问题就出在这儿。
- 必须写在要「开始新序列」的容器上,比如
.section { counter-reset: section; } - 如果想让每个
.chapter都从 1 开始编号,就得给每个.chapter单独加counter-reset: chapter; - 支持多个计数器同时重置:
counter-reset: item 0 section 1;,数字是起始值(默认为 0) - 注意层级:父元素设了
counter-reset,子元素用counter-increment才能继承上下文,否则会报“未定义计数器”
counter-increment 触发时机和常见失效原因
它只在元素被渲染时触发一次,且仅作用于匹配的元素本身,不递归子元素。最常踩的坑是:写了但没显示,或者编号跳变、重复。
- 必须配合
content和counter()或counters()才能看见效果,光写counter-increment不会自动出数字 - 伪元素里用错位置:比如写在
::before但忘了加content,或者把counter-increment写在::after里(无效) - 动态插入元素(如 JS append)后,不会自动补计数;需要手动触发重绘或确保样式已挂载
- display: none 的元素仍会触发
counter-increment,但 visibility: hidden 不会
counters() 嵌套计数时的分隔符陷阱
用 counters() 实现「1.1」「2.3.2」这类嵌套编号时,分隔符看似简单,实则容易漏掉关键细节。
- 第二个参数必须是字符串字面量,比如
counters(section, "."),不能是变量或 CSS 变量(不支持) - 如果父级没设
counter-reset,子级用counters()会静默失败,显示空内容 - 层级断开时(比如中间某层没设
counter-increment),编号会塌缩成单层,例如期望「2.1.1」却变成「2.1」 - 分隔符前后空格会被当作文本渲染,导致「1 . 1」这种难看格式,建议写成
"."而非". "
兼容性和性能要注意什么
这个功能在所有现代浏览器都稳定,但 IE11 是最后一道坎;性能方面,深层嵌套 + 大量元素可能拖慢渲染,尤其在旧版 Safari。
立即学习“前端免费学习笔记(深入)”;
- IE10+ 支持
counter-reset和counter-increment,但 IE11 及以下不支持counters()的第三个参数(样式) - 不要在
:hover或动画中频繁切换counter-increment,可能引发重排抖动 - 服务端渲染(SSR)时,CSS 计数器完全不执行,服务端看不到编号;需前端 hydrate 后才生效
- 可访问性差:屏幕阅读器通常忽略
content生成的内容,编号无法被读出,重要结构建议用真实文本或 ARIA 补充
counter-reset 或写错选择器。










