counter-increment比更灵活,因其可在任意元素触发计数、跨容器复用计数器、配合counter-reset控制起始值与作用域,并支持多计数器嵌套生成“1.1”“1.2”等层级编号,适用于自定义圆圈样式、条件编号及js动态内容混合场景。

为什么 counter-increment 比 <ol></ol> 更灵活
因为 <ol></ol> 只能生成线性、连续、不可跳变的数字序号,而 counter-increment 允许你:在任意元素上触发计数、跨容器复用同一计数器、配合 counter-reset 控制起始值和作用域、甚至用多个计数器嵌套生成 “1.1”“1.2” 这类层级编号。适合自定义样式圆圈、带条件跳过的列表(比如只给有标题的项编号)、或与 JS 动态内容混合的场景。
怎么写出带数字的圆圈样式(不依赖伪元素内容)
关键在于把计数器值注入 ::before 伪元素,并用 border-radius: 50% 和固定宽高形成圆圈。常见错误是忘记设置 display: inline-block 或 flex,导致圆圈无法居中对齐文字;或漏掉 counter-increment 导致数字始终为 0。
- 给父容器设
counter-reset: circle-counter(初始化计数器) - 给每个列表项(如
<li>或自定义<div class="item">)加 <code>counter-increment: circle-counter - 用
::before生成圆圈:.item::before { content: counter(circle-counter); display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 50%; background: #007bff; color: white; font-size: 14px; margin-right: 8px; } - 不要在 body 或全局样式里写
counter-reset: circle-counter,除非真要全局连续计数 - 若需跳过某项不计数,直接不加
counter-increment;若需显示固定数字(如 “①”),改用content: "①"而非依赖计数器
如何避免计数器全局污染或意外重置
如果页面多个区域都用 circle-counter,但希望各自从 1 开始,就必须用 counter-reset 在每个区域根元素上重新声明——否则后一个区域会接着前一个的末尾数字继续计。另一个坑是:块级元素(如 <div>)默认不参与计数器继承,必须确保目标元素是计数器作用域内的后代。
<ul>
<li>每个独立列表块加 <code>counter-reset: circle-counter,例如:<section class="list-group"></section>
兼容性和字体 fallback 怎么处理
所有现代浏览器都支持 counter(),但圆圈内数字居中依赖 flex 布局,IE10+ 支持有限。更隐蔽的问题是:某些系统字体(尤其中文环境下的默认 sans-serif)会让数字在小圆圈内上下偏移,看起来不居中。
- 强制使用等宽字体提升一致性:
font-family: "SF Mono", "Segoe UI Mono", "Roboto Mono", monospace - 避免用
line-height居中,优先用display: flex + align-items/justify-content - 圆圈尺寸小于 24px 时,建议把
font-size设为12px或13px,否则数字边缘会被裁切
counter-reset 的作用域边界、counter-increment 的触发时机、以及小尺寸下字体渲染的不可控性,才是最常卡住的地方。











