counter-reset 是一次性 css 声明,仅在元素渲染时触发,须设于最近公共祖先上;多计数器需显式指定顺序与初值;display: none 元素不参与计数,visibility: hidden 则仍计入。

counter-reset 不是用来“每天重置”或“定时重置”的,它是一次性 CSS 声明,只在元素渲染时触发重置动作——换句话说,它不响应时间、用户操作或 JS 重新计算,只依赖 DOM 结构和样式规则是否生效。
counter-reset 必须写在父容器上才有效
很多人把 counter-reset 错误地加在要编号的元素(比如 h2)自身上,结果编号全乱:计数器没被提前创建,counter-increment 就找不到目标。
- 正确做法:在包含所有编号项的**最近公共祖先**上设置
counter-reset,例如body、.article或section - 错误写法:
h2 { counter-reset: section; }—— 这会让每个h2都重置一次,编号永远是 1 - 典型结构:
.chapter { counter-reset: subsection; }+.chapter h3 { counter-increment: subsection; }
多个计数器共存时,顺序和初始值必须显式指定
像 counter-reset: chapter 1 section 0 这种写法,看似简单,但漏掉数字或顺序错位会导致嵌套编号断裂。浏览器按空格分词后依次处理,不会自动补默认值。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
- 如果只写
counter-reset: chapter section,两者都从 0 开始;但若希望chapter从 1 开始显示为 “第 1 章”,就得写chapter 0(因为counter-increment是先加再显示) - 多级编号中,子级计数器必须在父级递增后的元素上重置,例如:
h2 { counter-increment: chapter; counter-reset: section; } - 不要依赖继承:
counter-reset默认不继承,父设了,子级伪元素仍需自己counter-increment
display: none 的元素不触发 counter-reset 或 counter-increment
这是最容易被忽略的兼容性陷阱:隐藏元素(display: none)完全跳过计数器逻辑,但 visibility: hidden 或 opacity: 0 仍会参与计数。
- 动态切换显示状态时,用
visibility替代display可保持编号连续 - JS 操作 DOM 后插入新元素,只要它匹配对应选择器且
display不为none,就会正常参与计数 -
::before/::after伪元素若内容为空(content: ""),不影响计数器递增,但若content被设为none则整个伪元素不渲染,也不触发计数
真正难调的不是语法,而是当编号出现跳变或重复时,得回溯三层:看 counter-reset 写在哪、哪些元素实际匹配了 counter-increment、有没有隐藏节点悄悄吃掉了递增机会——DOM 树比想象中更“诚实”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










