必须用counter-reset+counter-increment+::before手动接管计数逻辑,因ol的type和start属性仅支持简单数字/字母类型及起始值,无法实现跳号、嵌套编号(如3.1)、前缀文字(如“第1章”)或跨容器续编等复杂需求。

用 counter-reset 和 counter-increment 控制 li 序号
HTML 默认的 ol 用的是简单递增数字,但很多场景下需要跳号、自定义起始值、或混合字母/罗马数字——这时不能靠改 value 属性硬塞(它只对 li 生效且不触发计数器重置),得用 CSS 计数器。
核心是三步:重置计数器 → 每个 li 自增 → 用 ::before 插入内容。
-
counter-reset放在父容器(如ol或ul)上,指定计数器名和起始值(默认为 0) -
counter-increment放在li上,每次渲染就 +1 -
content: counter(计数器名)写在li::before里,决定显示什么
ol.custom {
counter-reset: my-counter 10; /* 从 10 开始 */
}
ol.custom li {
counter-increment: my-counter;
}
ol.custom li::before {
content: counter(my-counter) ". ";
color: #666;
}
li 跳号或手动指定序号怎么办
纯 CSS 计数器是自动递增的,没法“跳过第 3 项”或“让第 5 项显示 ‘XII’”。这时候有两种现实解法:
- 用
value属性强行设单个li的序号(仅对ol下的li有效),例如:<li value="15">手动跳到 15</li>。但后续li会从 16 继续,不是“恢复自动” - 放弃计数器,直接在
li里写序号文本(比如<li> <span class="num">③</span>说明文字</li>),配合 JS 或后端生成——适合序号逻辑复杂、非线性、或带图标/符号的场景
注意:value 在 Firefox 中对 ol 外的 li(比如 ul 里)完全无效;Chrome 和 Safari 表现一致,但别指望跨浏览器稳定跳号。
用 list-style-type 切换序号样式但不改顺序
如果只是想把数字换成字母、罗马数字或中文数字,不需要动计数器逻辑,直接改 list-style-type 就行。它不影响序号值,只改显示形式。
-
list-style-type: lower-alpha→ a, b, c… -
list-style-type: upper-roman→ I, II, III… -
list-style-type: cjk-ideographic→ 一、二、三…(支持中日韩汉字,但需字体支持) -
list-style-type: none+counter()是最灵活的组合:既能控制值,又能自由排版
⚠️ 注意:cjk-ideographic 在某些旧系统或无中文字体的环境里会回退成方块或英文数字,别在关键路径上依赖它做可访问性保障。
为什么不用 ol start="5" 就够了?
start 属性确实能设起始数字,但它只能整数、不能设字母/符号、不支持负数、也不能重置子列表。更关键的是:一旦嵌套 ol,子 ol 默认从 1 开始,start 不继承也不联动。
- 单层简单编号 →
<ol start="3"></ol>最快 - 需要嵌套编号(如 3.1、3.2)、或每层不同样式(数字+字母)→ 必须用 CSS 计数器,配合
counter()嵌套调用 - 要兼容 IE8–IE11?CSS 计数器支持从 IE8 开始,但
counter()在 IE8 中不支持多参数(比如counter(name, lower-alpha)会失效)
真正容易被忽略的是:计数器名是全局作用域的。两个不相关的 ol 如果用了同一名字(比如都叫 my-counter),第二个会接着第一个的最终值继续计,而不是各自独立。命名加前缀或用局部作用域(如 BEM 类名绑定)能避开这个坑。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











