什么是 CSS 计数器?它能帮你做什么?
在网页开发中,我们经常需要为页面中的标题、列表、章节编号等元素自动添加序号。传统的做法是手动写 <li> 标签或在 HTML 中插入数字,但这种方式既繁琐又容易出错。有没有一种方法,能让浏览器自动为元素“数数”呢?答案就是——CSS 计数器。
CSS 计数器是 CSS 提供的一种强大功能,它允许你通过样式规则自动递增编号,而无需在 HTML 中手动编写序号。你可以把它想象成一个“自动记账本”:你只需要告诉它“从 1 开始,每遇到一个新项目就加 1”,剩下的工作就由 CSS 自己完成。
这种技术特别适合用于文档结构清晰的页面,比如文章目录、教学笔记、技术手册等。更重要的是,它完全基于样式控制,不依赖 JavaScript,性能高且语义清晰。
CSS 计数器的基本语法与工作原理
要使用 CSS 计数器,你需要掌握两个核心属性:counter-reset 和 counter-increment。它们就像一对搭档,一个负责“初始化”,一个负责“递增”。
counter-reset:初始化计数器
counter-reset 用于在指定元素上创建一个计数器,并设置起始值。默认值是 0,但你可以自定义。
/* 为所有 h2 元素创建一个名为 section 的计数器,从 1 开始 */
h2 {
counter-reset: section 1;
}
💡 注意:这里的
section是你自定义的计数器名称。你可以起任何名字,比如chapter、step、item等,只要前后一致即可。
counter-increment:递增计数器
counter-increment 用于让计数器在每次匹配元素时增加指定的值。如果不指定值,默认为 1。
/* 每遇到一个 h2,section 计数器就加 1 */
h2 {
counter-increment: section;
}
📌 小贴士:
counter-increment必须和counter-reset配合使用,否则计数器不会生效。
如何在内容中显示计数器值?
光有计数器还不行,你得让它“显示”出来。这就需要用到 content 属性和 counter() 函数。
content 与 counter() 函数
content 属性通常用于 ::before 或 ::after 伪元素,用来插入生成内容。而 counter() 函数就是用来获取某个计数器当前值的。
/* 在每个 h2 前面插入编号,格式为 "1. " */
h2::before {
content: counter(section) ".";
}
✅ 这里的
counter(section)返回当前section计数器的值,然后拼接上“.”符号。
完整示例:为标题自动编号
<article>
<h2>第一章:初识 CSS</h2>
<h2>第二章:布局基础</h2>
<h2>第三章:响应式设计</h2>
</article>
/* 初始化计数器 */
h2 {
counter-reset: section 1;
}
/* 每个 h2 触发一次递增 */
h2 {
counter-increment: section;
}
/* 在每个 h2 前显示编号 */
h2::before {
content: counter(section) ".";
margin-right: 8px;
font-weight: bold;
color: #333;
}
效果预览:
1.第一章:初识 CSS
2.第二章:布局基础
3.第三章:响应式设计
🎯 这就是 CSS 计数器的魅力:你只需要写一次 CSS,所有标题自动编号,修改起来也极其方便。
多级计数器:实现嵌套编号结构
现实场景中,标题往往是嵌套的。比如:
- 1.第一章
- 1.1.第一节
- 1.2.第二节
- 2.第二章
- 2.1.第一节
这时候就需要多级计数器了。CSS 支持嵌套计数器,只需为子元素重新 counter-reset 和 counter-increment。
实现嵌套编号的步骤
- 在父级元素上重置子计数器
- 在子元素上递增父级计数器
- 在子元素上递增子计数器
示例代码:实现章节与小节编号
<article>
<h2>第一章:基础语法</h2>
<h3>1.1.选择器</h3>
<h3>1.2.属性与值</h3>
<h2>第二章:布局模型</h2>
<h3>2.1.盒模型</h3>
<h3>2.2.浮动与清除</h3>
</article>
/* 为 h2 初始化主章节计数器 */
h2 {
counter-reset: subsection; /* 每个 h2 开始时重置 subsection */
counter-increment: section; /* 主章节递增 */
}
/* 为 h3 递增子节计数器 */
h3 {
counter-increment: subsection;
}
/* 在 h2 前显示主章节编号 */
h2::before {
content: counter(section) ".";
margin-right: 6px;
font-weight: bold;
color: #1a73e8;
}
/* 在 h3 前显示子节编号,格式为 "1.1" */
h3::before {
content: counter(section) "." counter(subsection);
margin-right: 6px;
font-size: 0.9em;
color: #555;
}
效果:
1.第一章:基础语法
1.1.选择器
1.2.属性与值
2.第二章:布局模型
2.1.盒模型
2.2.浮动与清除
🔍 妙处在于:
counter-reset: subsection会在每个h2后重新从 1 开始计数子节,实现了“每章独立编号”。
常见问题与实用技巧
1. 计数器不生效?检查这几点
- 是否遗漏了
counter-reset? - 是否在正确的元素上使用
counter-increment? content属性是否使用了::before或::after?- 是否使用了
display: none或visibility: hidden,导致伪元素无法渲染?
2. 如何自定义编号格式?
你可以使用 counter() 的第二个参数来指定计数器的样式:
h2::before {
content: counter(section, upper-roman) ".";
}
| 格式类型 | 示例 |
|---|---|
decimal |
1, 2, 3 |
lower-roman |
i, ii, iii |
upper-roman |
I, II, III |
lower-alpha |
a, b, c |
upper-alpha |
A, B, C |
✅ 这些格式支持在
counter()中直接使用,无需额外 JS 或模板。
3. 计数器可以重置为任意值吗?
当然可以。counter-reset 接受第二个参数,表示起始值。
h2 {
counter-reset: section 5; /* 从 5 开始 */
}
这在“从第 5 章开始”的文档中非常有用。
为什么推荐使用 CSS 计数器?
在现代网页开发中,我们常依赖 JavaScript 来实现动态编号,但这带来了额外的性能开销和维护成本。而 CSS 计数器的优势非常明显:
- ✅ 零 JavaScript 依赖:纯 CSS 实现,无需加载脚本
- ✅ 语义清晰:结构与样式分离,HTML 保持简洁
- ✅ 易于维护:修改编号规则只需改 CSS
- ✅ 支持打印样式:在打印页面时依然保持编号正确
- ✅ 兼容性良好:现代浏览器均支持
📌 尤其适合静态文档、教学网站、技术博客等场景。
实战案例:为博客文章生成目录编号
假设你正在写一篇《CSS 从入门到精通》系列文章,每篇文章都有多个小节。你可以用 CSS 计数器自动为每节生成编号。
<section class="article">
<h2>第一节:CSS 基础</h2>
<h3>1.1.选择器</h3>
<h3>1.2.属性详解</h3>
<h2>第二节:盒模型</h2>
<h3>2.1.边距与内边距</h3>
<h3>2.2.盒类型</h3>
</section>
.article h2 {
counter-reset: subsection;
counter-increment: section;
}
.article h3 {
counter-increment: subsection;
}
.article h2::before {
content: counter(section) ".";
font-weight: bold;
margin-right: 8px;
color: #d35400;
}
.article h3::before {
content: counter(section) "." counter(subsection);
font-size: 0.9em;
color: #666;
margin-right: 6px;
}
这样,你的文章目录就自动编号了,无论增加多少节,都不用手动改 HTML。
总结
CSS 计数器虽然不像 Flex 或 Grid 那样“热门”,但它是一个被低估的实用工具。它用极简的代码实现复杂的编号逻辑,真正体现了“样式驱动内容”的理念。
从单级编号到多级嵌套,从数字到罗马字母,CSS 计数器都能轻松应对。它不依赖 JS,不破坏语义,运行高效,是构建结构化文档的绝佳选择。
如果你还在为每个标题手动加序号而烦恼,不妨试试 CSS 计数器。它可能不会让你惊艳,但一定会让你省心。
记住:好的代码,不是写得多,而是用得巧。 而 CSS 计数器,正是这种“巧”的典范。