
本文介绍如何使用 CSS @property 和自定义动画,为网页中多个不同目标值的数字计数器(如年份、项目数、员工数等)创建平滑、独立的递增动画效果。
本文介绍如何使用 css `@property` 和自定义动画,为网页中多个不同目标值的数字计数器(如年份、项目数、员工数等)创建平滑、独立的递增动画效果。
在现代 CSS 中,借助 @property(CSS 自定义属性注册)和 counter() 函数,我们可以实现纯 CSS 驱动的整数计数器动画——无需 JavaScript。但一个常见误区是试图复用同一组 @keyframes 名称并多次覆盖定义(如多次声明 @keyframes counter),这会导致样式失效,因为 CSS 规范要求每个动画名称必须唯一。
要让多个计数器各自朝不同终点值(如 20、55、10、115)独立运行动画,关键在于:为每个计数器分配专属的 @keyframes 规则,并通过 CSS 自定义属性动态绑定动画名称与目标值。
✅ 正确实现步骤
-
注册自定义属性
--num
使用@property显式声明--num为<integer></integer>类型,确保其可被动画引擎正确插值:
@property --num {
syntax: '<integer>';
initial-value: 0;
inherits: false;
}</integer>
-
定义多个唯一命名的
@keyframes
每个计数器对应一个动画,to关键帧中指定其专属终值:
@keyframes counter-years {
from { --num: 0; }
to { --num: 20; }
}
@keyframes counter-projects {
from { --num: 0; }
to { --num: 55; }
}
@keyframes counter-employees {
from { --num: 0; }
to { --num: 10; }
}
@keyframes counter-customers {
from { --num: 0; }
to { --num: 115; }
}
-
统一应用动画逻辑,按需注入动画名
利用animation: var(--animation)实现“配置化”动画调用,并通过counter-reset绑定当前--num值:
div span {
counter-reset: num var(--num);
font: 800 40px system-ui;
padding: 2rem;
animation: var(--animation) 5s forwards ease-in-out;
}
div span::after {
content: counter(num) '+';
}
-
HTML 中按需指定动画类型
在每个<span></span>上通过内联样式或类设置--animation,精准匹配对应@keyframes:
<section style="display: flex; justify-content: space-around; align-items: center; height: 100%;"><div class="single-counter">
<div class="counter-contents">
<h2><span class="years-number" style="--animation: counter-years"></span></h2>
<h3>Years of Experience</h3>
</div>
</div>
<div class="single-counter">
<div class="counter-contents">
<h2><span class="project-number" style="--animation: counter-projects"></span></h2>
<h3>Complete Projects</h3>
</div>
</div>
<div class="single-counter">
<div class="counter-contents">
<h2><span class="employee-number" style="--animation: counter-employees"></span></h2>
<h3>Employees</h3>
</div>
</div>
<div class="single-counter">
<div class="counter-contents">
<h2><span class="customers-number" style="--animation: counter-customers"></span></h2>
<h3>Customers</h3>
</div>
</div>
</section>
⚠️ 注意事项
-
浏览器兼容性:
@property目前仅支持 Chrome 103+、Edge 103+、Safari 16.4+(Firefox 尚未支持)。生产环境建议添加 JS 回退方案。 -
counter()的局限性:counter(num)仅支持整数,且依赖counter-reset;无法直接格式化(如千分位),如需复杂格式请改用content-visibility+ JS 或attr()+ 数据属性。 -
性能提示:避免在大量元素上同时触发长时动画;可结合
intersection-observer实现滚动触发动画,提升首屏性能。 -
语义增强:为无障碍访问,建议为计数器添加
aria-live="polite"和role="status",并在动画结束后更新aria-valuenow。
通过该方案,你不仅解决了多计数器冲突问题,还构建了一套可扩展、易维护的 CSS 数值动画体系——只需新增 @keyframes 和对应 --animation 值,即可快速接入新指标。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











