必须用 CSS counter-reset 初始化计数器,否则 counter-increment 无效;通过 ::before 的 content 拼接 counter() 或 counters() 实现自定义序号、层级编号(如“1.1”)及前缀图标,注意作用域与 display 属性对渲染的影响。

直接用 ol 的默认序号没法加图标、换字体、插前缀,也做不到跨列表连续或嵌套层级拼接。必须用 CSS counter-reset + counter-increment 手动接管编号逻辑。
为什么只写 counter-increment 却没数字显示
因为没初始化——counter-increment 不是“从 0 开始加”,而是“在已有计数器上加 1”。没 counter-reset,计数器根本不存在,结果全是 0 或不渲染。
- 必须在父容器(如
ul、section或任意块级包装元素)上写counter-reset: item; -
counter-reset: item 5;表示“初始值设为 5”,第一次counter-increment后才取到6,别误以为是“从 5 开始显示” - 如果把
counter-reset错写在li上,每个li都重置一次,结果全显示1
怎么让序号带括号、图标或中文前缀
靠 ::before 的 content 拼接,不是靠 class 或 JS 插入文本。
-
li::before { content: "Step " counter(item) ": "; }→ 渲染为 “Step 1: ” -
li::before { content: "①" counter(item, lower-alpha) " "; }→ “①a ”、“①b ”(注意:样式关键字不能加引号,lower-alpha✅,"lower-alpha"❌) - 想加 SVG 图标?得用 background-image 或 inline SVG,
content只接受字符串和counter()函数调用,不支持 HTML 标签
嵌套列表怎么出 “1.1”、“1.2”、“2.1” 而不是全平级
单靠 counter() 拼不出层级,得用 counters()(复数形式),且父子必须共用同一个计数器名。
立即学习“前端免费学习笔记(深入)”;
- 外层
ul设counter-reset: section;,每个外层li写counter-increment: section; - 内层
ul不要另起名字,也用counter-reset: section;(重置子级作用域),其li同样counter-increment: section; - 内层
li::before { content: counters(section, ".") ". "; }→ 自动拼出 “1.1”、“1.2”、“2.1” - 如果子级用了不同名字(比如
subsection),counters()就找不到父级值,会退化成单级编号
响应式布局下序号错位或断层
不是计数器失效,是伪元素在 flex/grid 中默认行为导致对齐失控,或媒体查询里漏了重置声明。
- 在
li::before上显式加display: inline-block;或flex-shrink: 0;,否则可能被挤换行 - 多列(
column-count)天然连续,不用额外处理;但display: grid布局时,建议给li::before设min-width: 2em;+text-align: right;对齐数字右端 - 媒体查询切换布局时,若父容器变了(比如从
ul换成div.grid),记得在新容器上补counter-reset: item;,否则计数器丢失初始值
最易忽略的是:计数器基于 DOM 顺序执行,跟 visibility、opacity 无关;但 display: none 的元素不会触发 counter-increment。调试时别只看渲染结果,先查元素是否在 DOM 中、counter-reset 是否落在正确父级、content 有没有拼错函数名。


















