css计数器需counter-reset与counter-increment成对使用,仅设其一无效;动画中须用steps()配合counter-increment实现离散跳变,且不支持小数、格式化及暂停恢复。

counter-reset 和 counter-increment 必须成对出现才能驱动数字变化
只设 counter-reset 不触发计数,只写 counter-increment 但没初始化,content 里显示为空或 0。浏览器不会自动创建计数器,必须先 counter-reset: percent 0,再在伪元素里用 counter-increment: percent 触发递增。
常见错误是把 counter-increment 放在父容器上却期望子元素的 ::after 显示变化——它只对当前元素生效,且每次渲染帧都需重新触发(靠动画重绘)。
- 计数器名区分大小写,
percent和Percent是两个计数器 - 初始值建议显式写
counter-reset: percent 0,不依赖默认值,避免 Safari 或旧版 Chrome 行为不一致 - 若需从 0% 跳到 100%,中间跳过 50%,得靠动画关键帧逐帧调用
counter-increment,不能靠 CSS 自动插值
content 动画必须配合 animation-timing-function + steps() 才能“跳”起来
CSS 计数器本身不支持小数或百分比格式化,content: counter(percent) "%" 只能输出整数。想实现「0→1→2→…→100」的离散跳变,不能用 ease 或 linear,否则数字会模糊、重叠甚至闪退——因为浏览器在中间帧尝试渲染未定义的计数值(比如 counter(12.7) 无效,回退为空)。
正确做法是用 steps(100, end) 把 1s 动画切成 100 步,每步触发一次 counter-increment,确保每帧只进 1。
立即学习“前端免费学习笔记(深入)”;
-
steps(100, end)中的end表示在每步结束时才更新,避免首帧就显示 1% - 动画时长和 steps 数量要匹配:1s 动画配
steps(100)≈ 每 10ms 一跳;若改成 2s,steps 也得翻倍,否则跳变变慢 - Firefox 对
counter-increment在@keyframes里的支持较晚(v100+),低于此版本会静止在初始值
百分比符号 "%" 不能直接塞进 counter(),得拼接在 content 里
counter(percent) 只返回数字,强行写 counter(percent "%") 语法错误,浏览器直接忽略整个 content 声明。必须分开拼:content: counter(percent) "%"。
如果需要补零(如 001%)、千分位(1,000%)或小数(99.5%),CSS 原生 counter 无能为力——它不支持格式化函数。这时候就得换思路:用 JS 控制 data- 属性,或改用 attr(data-pct) 配合 JS 更新。
- 想显示「加载中… 67%」,文字部分用真实文本,百分比用伪元素覆盖,避免布局抖动
- 移动端要注意
content伪元素触发重排成本低,但频繁触发仍可能卡顿,别在滚动区域里滥用 - 若需兼容 IE,彻底放弃 counter 方案,改用 JS +
innerText更新
animation-play-state: paused / running 控制跳动启停很脆弱
想暂停加载动画时调 element.style.animationPlayState = "paused",看起来停了,但计数器状态其实已“卡死”:后续恢复播放不会从暂停处继续,而是重播整个动画——因为 counter-increment 没有记忆,只响应当前帧的声明。
这意味着无法靠纯 CSS 实现「暂停/恢复」逻辑。真要控制进度,得用 JS 记录当前值,再通过修改 counter-reset 的初始值 + 重置动画来模拟。
- 不要依赖
animationiteration事件监听跳动完成,它在steps()下行为不可靠 - 用
getComputedStyle(el).content读不到实时 counter 值,只能读原始字符串如"counter(percent) "%" - 最稳的暂停方式:用 JS 清除 class,停止动画,同时用
dataset.pct = currentVal保存进度










