CSS 计数器是由 CSS 维护的变量,这些变量可根据 CSS 规则增加从而跟踪使用次数。我们可以利用这个特性,根据文档位置来调整内容表现,比如显示列表编号。
最近在公司官网就用到了这个特性:
image.png
因为这里的序号只是个装饰,并不强调先后顺序。比起使用真实 DOM 元素显示序号,CSS 计数器更加简洁灵活,万一内容顺序需要调整,序号也不受影响。
有时候我们会看到某些 Dashboard 界面有数字快速滚动的效果,比如招行 App 的账户余额。这种效果怎么实现呢?本文会介绍几种方法。
JavaScript 方案
最简单的莫过于用setInterval定时器了,定期修改 DOM 内容就行。不过为了实现更平顺的动画效果,更推荐使用requestAnimationFrame:
functionanimateValue(obj,start,end,duration){ letstartTimestamp=null; conststep=(timestamp)=>{ if(!startTimestamp)startTimestamp=timestamp; constprogress=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);
js.gif
CSS @keyframes 结合 margin
这个思路比较有意思,原理是把数字排成一行,通过动画移动元素位置来显示不同位置的数字:
012345678910
.counter{ width:100px; overflow:hidden; } .numbers{ width:auto; display:flex; animation:countNumber4sinfinitealternate; animation-timing-function:steps(10); } .numbersdiv{ text-align:center; flex:00100px; } @keyframescountNumber{ 0%{ margin-left:0px; } 100%{ margin-left:-1000px; } }
keyframe.gif
CSS 计数器入门版
CSS 计数器使用到以下几个属性:
counter-reset - 创建或者重置计数器
counter-increment - 递增变量
content - 插入生成的内容
counter() 或 counters() 函数 - 将计数器的值添加到元素
要使用 CSS 计数器,得先用 counter-reset 创建。结合 CSS 动画@keyframes,在动画的不同阶段设置不同的递增值,就能实现这个效果:
div::after{ content:counter(count); animation:counter3slinearinfinitealternate; counter-reset:count0; } @keyframescounter{ 0%{ counter-increment:count0; } 10%{ counter-increment:count1; } 20%{ counter-increment:count2; } 30%{ counter-increment:count3; } 40%{ counter-increment:count4; } 50%{ counter-increment:count5; } 60%{ counter-increment:count6; } 70%{ counter-increment:count7; } 80%{ counter-increment:count8; } 90%{ counter-increment:count9; } 100%{ counter-increment:count10; } }
CSS 计数器高配版
更进一步,如果敢用最新特性,其实有更秀的操作,那就是给 CSS 变量设置动画。这个技巧的核心就是设置 CSS 自定义属性为整数类型,这样就能像其他拥有整数类型值的 CSS 属性一样,可用于transition中了。
@property--num{ syntax:''; initial-value:0; inherits:false; } div{ transition:--num1s; counter-reset:numvar(--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:""; 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*/
完整代码:
@property--percent{ syntax:""; initial-value:0; inherits:false; } @property--temp{ syntax:" "; initial-value:0; inherits:false; } @property--v1{ syntax:" "; initial-value:0; inherits:false; } @property--v2{ syntax:" "; initial-value:0; inherits:false; } div{ font:80040pxmonospace; padding:2rem; transition:--percent1s; --temp:calc(var(--percent)*100); --v1:max(var(--temp)-0.5,0); --v2:max((var(--temp)-var(--v1))*100-0.5,0); counter-reset:v1var(--v1)v2var(--v2); } div::before{ content:counter(v1)"."counter(v2,decimal-leading-zero)"%"; }
constgenNumber=()=>{ document.querySelector("div").style.setProperty("--percent",Math.random()); }; setInterval(genNumber,2000); setTimeout(genNumber);
编辑:hfy
-
javascript
+关注
关注
0文章
519浏览量
53897 -
CSS
+关注
关注
0文章
109浏览量
14391 -
DOM
+关注
关注
0文章
18浏览量
9591
发布评论请先 登录
相关推荐
评论