CSS当初可不仅仅只是改一个色彩这么简略,还能够做很多交互,比方做一个功能齐全的计时器?
款式上并不简单,次要是几个交互的中央
- 数字时钟的变动
- 开始、暂停操作
- 重置操作
如何仅应用 CSS 来实现这样的性能呢?一起看看吧
一、数字时钟的变动
这个性能之前在这篇文章中有具体介绍,有趣味的能够回顾一下
还在应用定时器吗?CSS 也能实现电子时钟
这里简略介绍一下实现原理
在以前,如果要实现数字的递增变动,可能须要提前准备好这些数字,例如像这样
<span> <i>1</i> <i>2</i> ... <i>59</i></span>
或者用伪元素创立也行
span::before{ content: '1\A 2\A 3\A ... 59'}
这种形式须要创立多个标签,稍微繁琐,也不易扩大。当初有更简洁的形式能够实现了,那就是 CSS @property。这是干什么的呢?简略来讲,能够自定义属性,在这个例子中,能够让数字像色彩一样进行过渡和动画,可能不太懂,间接看例子吧
假如 HTML 是这样的
<span style="--num: 0"></span>
咱们让这个自定义变量在页面中展现进去,单纯的 content
无奈间接显示自定义变量,须要借助计数器,有趣味的能够参考这篇文章:小tips: 如何借助content属性显示CSS var变量值
span::after{ counter-reset: num var(--num); content: counter(num);}
当初能够通过:hover
扭转这个数字
span:hover::after{ --num: 59}
很僵硬的从 0 变成 59 了,十分合乎惯例,因为--num
并不反对过渡动画。如果利用 CSS property,状况就不一样了,须要革新的中央很少,先定义一下--num
,而后给这个变量一个过渡工夫,如下
@property --num { syntax: '<integer>'; inherits: false; initial-value: 0;}span::after{ transition: 1s --num;}
神奇的一幕产生了
看着如同不堪设想?能够这么了解,通过@property
定义后,这个变量自身能够独自设置过渡了,而不再取决于一些仅反对过渡的属性(color
、width
等)。还能够应用动画,如下
@keyframes num { to { --num: 10 }}span{ animation: num 1s infinite steps(10);}
数字变动的基本原理就是这样了,一个有限循环的 CSS 动画!
回到这里,这里须要的是一个秒表,分为“分”、“秒”、“毫秒”(这里的毫秒就用 1/100秒来代替),3个数字的动画时长都不统一,所以须要定义3个 CSS 变量,残缺实现如下
@keyframes minitus { to { --m: 59 }}@keyframes seconds { to { --s: 59 }}@keyframes ms { to { --ms: 99 }}span{ counter-reset: minitus var(--m) seconds var(--s) ms var(--ms); animation: minitus 3600s infinite steps(60, end), seconds 60s infinite steps(60, end), ms 1s infinite steps(100, end);}span::before{ content: counter(minitus, decimal-leading-zero) ':' counter(seconds, decimal-leading-zero) ':' counter(ms, decimal-leading-zero);}
这样就失去了一个主动运行的秒表
二、开始、暂停操作
首先思考一下,CSS 须要怎么记住点击操作?答案就是input type="checkbox"
(通过label
关联),能够这样来布局
<div class="counter"> <input type="checkbox" id="start" hidden> <label class="btn start" for="start"></label> <label class="btn reset">重置</label> <div class="clock"></div></div>
因为须要通过input:cheked
来管制秒表的状态,须要借助后置兄弟选择器~
来实现,所以input
须要在后面(当然,当初有了:has
也能够不须要这样)。
这里能够通过grid
布局来灵便摆放各个模块的地位
.counter{ display: grid; grid-template-areas: "clock clock" "start reset"}.start{ /**/ grid-area: start;}.reset{ /**/ grid-area: reset;}
简略丑化当前,能够失去这样的成果
而后,因为秒表的运行其实就是一个 CSS 动画,所以咱们能够间接用:cheked
来管制动画的状态,默认设置成暂停的,还有按钮文字也能够通过::before
来生成,实现如下
.clock{ animation-play-state: paused;/*默认暂停*/}.start::before{ content: '开始';}:checked~.start::before{ content: '暂停';}:checked~.clock{ animation-play-state: running;}
这样就能够通过按钮手动管制开始和暂停了
三、重置操作
重置看起来如同有点麻烦,有点无从下手。
其实重置一个动画非常简单,间接将动画勾销就能够了,也就是相当于重置了动画,如下
.reset:active+.clock{ animation: none;}
其次,重置个别只有在暂停时才可用,所以还须要用后面的:checked
禁用一下,并且视觉上能够透明度升高一点,实现如下
:checked~.reset{ opacity: .65; pointer-events: none;}
这样就失去了文章结尾所示的成果
当然,你还能够应用自定义字体,比方DigitalNumbers
残缺代码能够查看以下任意链接:
- CSS counter (codepen.io)
- CSS counter (runjs.work)
四、会影响业务逻辑吗?
还有一点,有同学放心 CSS 只是视觉层面的,可能会影响业务逻辑。
的确,因为是伪元素渲染,页面上看不到任何数字,也就是无奈间接通过innerText
获取以后工夫,然而,咱们能够借助getComputedStyle
来失去 CSS 变量
getComputedStyle($0).getPropertyValue('--ms')
实时获取如下
所以通过 CSS 形式也是齐全不影响业务逻辑的
五、兼容性和总结
因为在实现中用到了CSS @property
个性,这是CSS Houdini
的一部分,目前只有 Chrome 反对(惋惜了)。让人惊奇的是,Safari
竟然在前不久也反对了这个个性,将来可期,如下
当然这不是重点,只是这种形式实现更加简洁而已,齐全能够用传统形式来实现,有趣味的能够尝试一下。
上面总结一下实现要点
- CSS 当初很弱小,不仅仅只是款式,还能做很多交互
CSS @property
能够使CSS变量反对动画- 数字时钟的变动其实是一个CSS变量一直递增循环的动画
- CSS 点击操作状态能够通过
:checked
管制 - Grid 布局能够很不便的管制各个元素的地位
- 计时器开始和暂停其实就是动画的运行和暂停
- 间接将动画勾销就相当于重置了整个动画
最初,如果感觉还不错,对你有帮忙的话,欢送点赞、珍藏、转发❤❤❤