h2/h3编号异常的根本原因是css计数器未正确重置或递增;需在最外层容器设counter-reset,在h2上设counter-increment和counter-reset: subsection,在h3上设counter-increment,并用counters()自动嵌套生成编号。

为什么 h2/h3 编号总是从 1 开始或跳号
根本原因是计数器没被正确重置或递增。浏览器不会自动为标题层级建计数器——你得手动定义每个层级的作用域起点和累加点。
counter-reset: section; 必须写在最外层容器上(比如 <article></article> 或 ),不能只写在 h2 上,否则每个 h2 都重置自己,结果全是「1」。
-
h2要触发一级递增:counter-increment: section; -
h2上还要加counter-reset: subsection;(注意:这行写在h2上,不是h3上),确保每个h2下的子级从 1 重新开始 -
h3必须有counter-increment: subsection;,漏掉就永远显示 0
如何让 h2 显示 1、2、3,h3 显示 1.1、1.2、2.1
关键不是拼字符串,而是用 counters() 自动提取嵌套深度。它比手动写 counter(section) "." counter(subsection) 更可靠,避免空段(如「1..」)。
正确写法示例:
article { counter-reset: section; }
h2 { counter-increment: section; }
h2::before { content: counter(section) ". "; }
h2 { counter-reset: subsection; }
h3 { counter-increment: subsection; }
h3::before { content: counters(section, ".") ". "; }
这里 counters(section, ".") 会自动按 DOM 嵌套路径取值:第一个 h2 下的 h3 输出「1.1」,第二个 h2 下的第一个 h3 输出「2.1」。
响应式布局下编号断层怎么办
不是 counters() 失效,而是媒体查询割裂了 counter-reset 与 counter-increment 的作用域。桌面端在 .toc 上设了 counter-reset: section subsection;,但移动端改用 display: flex 重排结构时,若没在对应容器上同步重置,子项就继承不到初始值——结果可能是“1.1”跳成“0.1”,或二级编号全为 0。
- 必须在每个断点内,对实际渲染的父容器重新声明
counter-reset,不能只靠顶层一次设置 -
.toc ul和.toc li ul选择器差异会影响重置时机,务必根据实际 HTML 结构调整 - 伪元素
::before在 flex/grid 容器中默认display: inline,需显式设display: inline-block或flex,否则序号文字容易换行、错位 - 用
display: none隐藏列表项 → 计数跳过;用visibility: hidden→ 计数仍递增(这是预期行为,但常被误以为 bug)
嵌套列表里子级编号全乱,怎么配计数器名
同一级嵌套不能复用计数器名。比如外层 .list-group 用了 counter-reset: item;,内层 .list-group-item > ul 必须用不同名,如 counter-reset: subitem;,否则子列表会覆盖而非延续编号。
- 想让子列表从 1 重新开始,必须显式写
counter-reset: subitem;,且该声明要作用于子容器自身(如ul元素),而非它的父元素 - 计数器名区分大小写,只允许字母、数字、短横线,不能含空格或特殊符号
-
counter-increment可带步长(如counter-increment: section 2),也可同时递增多个(如counter-increment: section chapter) -
counters()第二个参数是分隔符,必须加引号,如counters(section, "."),不加引号会导致解析失败
DOM 嵌套结构是 counters() 层级识别的唯一依据,扁平化布局(如用 display: contents 或 JS 动态打乱顺序)会让编号断裂——这不是 bug,是设计使然。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











