持续进步的同窗都关注了“1024译站”web
CSS 计数器是由 CSS 维护的变量,这些变量可根据 CSS 规则增长从而跟踪使用次数。咱们能够利用这个特性,根据文档位置来调整内容表现,好比显示列表编号。浏览器
最近在公司官网就用到了这个特性:
微信

由于这里的序号只是个装饰,并不强调前后顺序。比起使用真实 DOM 元素显示序号,CSS 计数器更加简洁灵活,万一内容顺序须要调整,序号也不受影响。app
有时候咱们会看到某些 Dashboard 界面有数字快速滚动的效果,好比招行 App 的帐户余额。这种效果怎么实现呢?本文会介绍几种方法。dom
JavaScript 方案
最简单的莫过于用 setInterval
定时器了,按期修改 DOM 内容就行。不过为了实现更平顺的动画效果,更推荐使用 requestAnimationFrame
:函数
function animateValue(obj, start, end, duration) {
let startTimestamp = null;
const step = (timestamp) => {
if (!startTimestamp) startTimestamp = timestamp;
const progress = Math.min((timestamp - startTimestamp) / duration, 1);
obj.innerHTML = Math.floor(progress * (end - start) + start);
if (progress < 1) {
window.requestAnimationFrame(step);
}
};
window.requestAnimationFrame(step);
}
const obj = document.getElementById("value");
animateValue(obj, 100, 0, 5000);

CSS @keyframes 结合 margin
这个思路比较有意思,原理是把数字排成一行,经过动画移动元素位置来显示不一样位置的数字:flex
<div class="counter">
<div class="numbers">
<div>0</div>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
</div>
</div>
.counter {
width: 100px;
overflow: hidden;
}
.numbers {
width: auto;
display: flex;
animation: countNumber 4s infinite alternate;
animation-timing-function: steps(10);
}
.numbers div {
text-align: center;
flex: 0 0 100px;
}
@keyframes countNumber {
0% {
margin-left: 0px;
}
100% {
margin-left: -1000px;
}
}

CSS 计数器入门版
CSS 计数器使用到如下几个属性:动画
counter-reset - 建立或者重置计数器spa
counter-increment - 递增变量.net
content - 插入生成的内容
counter() 或 counters() 函数 - 将计数器的值添加到元素
要使用 CSS 计数器,得先用 counter-reset 建立。结合 CSS 动画 @keyframes
,在动画的不一样阶段设置不一样的递增值,就能实现这个效果:
<div></div>
div::after {
content: counter(count);
animation: counter 3s linear infinite alternate;
counter-reset: count 0;
}
@keyframes counter {
0% {
counter-increment: count 0;
}
10% {
counter-increment: count 1;
}
20% {
counter-increment: count 2;
}
30% {
counter-increment: count 3;
}
40% {
counter-increment: count 4;
}
50% {
counter-increment: count 5;
}
60% {
counter-increment: count 6;
}
70% {
counter-increment: count 7;
}
80% {
counter-increment: count 8;
}
90% {
counter-increment: count 9;
}
100% {
counter-increment: count 10;
}
}
CSS 计数器高配版
更进一步,若是敢用最新特性,其实有更秀的操做,那就是给 CSS 变量设置动画。这个技巧的核心就是设置 CSS 自定义属性为整数类型,这样就能像其余拥有整数类型值的 CSS 属性同样,可用于 transition
中了。
@property --num {
syntax: '<integer>';
initial-value: 0;
inherits: false;
}
div {
transition: --num 1s;
counter-reset: num var(--num);
}
div:hover {
--num: 10000;
}
div::after {
content: counter(num);
}
不过须要注意的是,目前只有 Chrome (或者 Chromium 内核的浏览器好比 Edge 和 Opera)支持 @property
语法,所以兼容性是个问题。若是你的页面只针对 Chrome(好比 Electron 应用),那就能够放心使用。不然仍是用前面的保守方案吧。
小数也能玩动画
前面说的变量都要求是整数,那能不能让小数也支持这种动画呢?答案是能够的。
能够把小数转成整数。步骤原理是:
注册一个整型的 CSS 变量(即
--number
),指定初始值initial-value
。用
calc
将值取整:--integer: calc(var(--number))
@property --integer {
syntax: "<integer>";
initial-value: 0;
inherits: false;
}
--number: 1234.5678;
--integer: calc(var(--number)); /* 1235 */
若是只须要提取整数部分,能够这样: --integer: max(var(--number) - 0.5, 0)
,连calc()
都不须要了。相似方法能够提取小数部分。
/* @property --integer */
--number: 1234.5678;
--integer: max(var(--number) - 0.5, 0); /* 1234 */
完整代码:
<div></div>
@property --percent {
syntax: "<number>";
initial-value: 0;
inherits: false;
}
@property --temp {
syntax: "<number>";
initial-value: 0;
inherits: false;
}
@property --v1 {
syntax: "<integer>";
initial-value: 0;
inherits: false;
}
@property --v2 {
syntax: "<integer>";
initial-value: 0;
inherits: false;
}
div {
font: 800 40px monospace;
padding: 2rem;
transition: --percent 1s;
--temp: calc(var(--percent) * 100);
--v1: max(var(--temp) - 0.5, 0);
--v2: max((var(--temp) - var(--v1)) * 100 - 0.5, 0);
counter-reset: v1 var(--v1) v2 var(--v2);
}
div::before {
content: counter(v1) "." counter(v2, decimal-leading-zero) "%";
}
const genNumber = () => {
document.querySelector("div").style.setProperty("--percent", Math.random());
};
setInterval(genNumber, 2000);
setTimeout(genNumber);

顺手点“在看”,天天早下班;转发加关注,共奔小康路~
本文分享自微信公众号 - 1024译站(trans1024)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。