CSS计数器通过counter-reset和counter-increment实现原生章节编号,需在容器设reset、标题设increment,配合::before和content拼接编号;支持decimal/alpha/roman等格式,但无中文数字;语义优于ol,兼容性和PDF导出更优。

用 counter-reset 和 counter-increment 控制编号起始与递增
浏览器原生支持章节自动编号,不靠 JS 也能做,关键是用好 CSS 计数器。默认从 1 开始,但实际写文档常要跳过前几章(比如封面、目录页),或让附录从 A 开始——这时候不能只靠 counter-increment,必须配 counter-reset 显式重置。
常见错误是只在 h2 上加 counter-increment: section,结果所有 h2 累加成一个序列,没法分章节独立编号。正确做法是:在章节容器(如 section)上设 counter-reset: subsection,再在子标题上递增对应层级。
-
counter-reset: section写在article或section元素上,表示该容器内section计数器从 0 开始 -
counter-increment: section写在h2上,每次出现就 +1 - 嵌套编号(如 2.1、2.1.1)需多级计数器:
counter-reset: subsection放在h2里,counter-increment: subsection放在h3里 - IE11 及更早版本不支持
counter-set(用于精确设值),如需兼容,避免用它设非零初始值
用 ::before 和 content 拼接编号与标题文本
编号本身不显示,得靠伪元素注入。重点不是“怎么显示”,而是“怎么拼得对”:章节号、点、空格、标题文字的组合顺序和空格处理容易出错。
典型翻车场景:用 content: "第 " counter(section) " 章 ",结果“第”和数字间多一个空格;或者用 content: counter(section) ". " 后标题换行,点和文字断开了。
- 用
content: counter(section) "."最稳妥,点紧跟数字,无多余空格 - 需要前缀(如“第”“附录”)时,用
content: "第" counter(section) "章 ",注意中文标点后跟空格是排版习惯,但 CSS 里空格会被压缩,建议用\a0(不间断空格)替代普通空格 - 若标题含 HTML 标签(如
),::before拼接的编号不会受其样式影响,这是优点也是限制——别指望用em斜体去影响编号 - Chrome 和 Firefox 对
content中 Unicode 字符支持一致,但旧 Safari 在content: counter(section, upper-alpha)里可能不渲染大写字母,测试时务必真机看
用 counter() 的 style 参数切换编号格式
数字、字母、罗马字这些不是靠 JS 判断生成的,是 CSS 原生能力。但参数名和效果不完全直觉——比如 lower-roman 是小写罗马字(i, ii, iii),而 upper-roman 才是大写(I, II, III),很多人试了 roman 发现不生效,其实是没写全。
另一个坑是中文数字:CSS 标准不支持 chinese 这类值,simp-chinese 仅在部分浏览器实验性支持,生产环境别用。
- 可用值包括:
decimal(1,2,3)、lower-alpha(a,b,c)、upper-alpha(A,B,C)、lower-roman(i,ii,iii)、upper-roman(I,II,III) -
counter(section, lower-alpha)用在附录小节很自然,但注意:一旦计数器值超过 26,Chrome 会回退到数字,Firefox 可能显示空,别假设它会自动进位成 aa、ab - 想用“一、二、三”,只能靠 JS 或预生成,CSS 无解
- 多个计数器同名但不同 style 不会冲突,
counter(section)和counter(section, upper-alpha)可共存,各自按规则渲染
为什么不用 ol + li 做章节编号
因为语义不对,且结构僵硬。ol 是有序列表,适用于步骤、选项这类线性集合,而章节是嵌套大纲,标题层级靠 h1~h6 表达语义,不是“第几个条目”。
硬套 ol 的后果:屏幕阅读器把“第二章”读成“列表项 2”,丢失“章”这个语义;SEO 抓取时可能忽略标题权重;改用 CSS 隐藏序号后,li 的默认 margin/padding 还得额外清,反而更麻烦。
-
h2的语义是“二级标题”,不是“第二个标题”,编号只是视觉辅助,不该绑架结构 - 如果真用
ol,start属性只能设整数起始值,无法实现“附录 A”这种字符起始 - 响应式场景下,
ol的缩进逻辑和标题流式布局经常打架,尤其在 flex/grid 容器里,counter更可控 - 最实际的一点:PDF 导出工具(如 PrinceXML)对 CSS 计数器的支持远好于对
ol的语义还原,章节页码和交叉引用更稳
真正难的不是写对那几行 CSS,而是想清楚“哪些该重置、哪些该继承、哪些该隔离”。比如法律条文里“第X条”和“第X款”的编号关系,或技术文档中“图1-1”“表2-3”的跨章节引用——这时候计数器作用域和命名就得提前规划好,不然后期改起来比重写还累。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











