
本文介绍如何使用 CSS @property 和自定义动画,为页面中多个不同目标值的数字计数器分别创建平滑、独立的递增动画,避免动画覆盖与样式冲突。
本文介绍如何使用 css `@property` 和自定义动画,为页面中多个不同目标值的数字计数器分别创建平滑、独立的递增动画,避免动画覆盖与样式冲突。
在现代 CSS 中,利用 @property 声明自定义属性(如 --num)并配合 counter() 函数,可实现无需 JavaScript 的纯 CSS 数值动画。但需注意:同一名称的 @keyframes 规则不可重复定义,否则后声明者将覆盖前者——这正是原始代码中所有计数器最终都显示相同数值(如全部停在 115)的根本原因。
✅ 正确实现思路
核心在于 “一元素一动画” + “动态动画绑定”:
- 为每个计数目标(年份、项目数、员工数、客户数)定义唯一命名的
@keyframes; - 利用
animation: var(--animation)将动画名作为可变值注入元素; - 通过内联
style="--animation: counter-years"精准控制每个所使用的动画。
? 完整可运行代码示例
/* 基础重置与字体 */
html, body {
width: 100%; height: 100%;
}
* { box-sizing: border-box; }
body {
margin: 0; padding: 0;
font-family: 'Roboto', 'Segoe UI', Verdana, Helvetica, sans-serif;
font-size: 16px;
}
/* 声明受控整数属性 */
@property --num {
syntax: '<integer>';
initial-value: 0;
inherits: false;
}
/* 统一计数器样式与动画入口 */
div span {
counter-reset: num var(--num);
font: 800 40px system-ui;
padding: 2rem;
display: inline-block;
animation: var(--animation) 5s forwards ease-in-out;
}
/* 共享伪元素内容:数字 + '+' 符号 */
div span::after {
content: counter(num) '+';
}
/* 各自独立的动画定义(关键!不可重名) */
@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; }
}</integer>
<section style="display: flex; justify-content: space-around; align-items: center; height: 100vh; gap: 1rem;"><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 回退逻辑。 -
动画触发时机:CSS 计数器动画在元素进入渲染流时自动播放;若需滚动触发动画,需结合
intersectionObserver+animation-play-state控制。 -
性能优化:避免对大量元素同时启用高频率动画;本方案中
counter()是 CSS 原生计算,性能远优于 JSrequestAnimationFrame手动更新textContent。 -
可维护性增强:可将
--animation值提取至 CSS 类(如.counter-years { --animation: counter-years; }),提升 HTML 可读性。
通过该方案,你不仅能精准控制每个计数器的目标值与动画行为,还构建了可扩展的 CSS 动画架构——后续新增计数项,只需增加一组 @keyframes 和对应类/内联样式即可,真正实现「一次配置,多处复用」。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











