服务粉丝

我们一直在努力
当前位置:首页 > 财经 >

【第2925期】纯 CSS 实现一个计时器

日期: 来源:前端早读课收集编辑:XboxYan

前言

去 JS 化实现计时器,其实通过这种案例蛮可以探索点。今日前端早读课文章由 @XboxYan 分享,公号:前端侦探授权。

前端早读课:有用的文章,值得看第二遍

正文从这开始~~

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>

我们让这个自定义变量在页面中展示出来,单纯的 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

完整代码可以查看以下任意链接:https://codepen.io/xboxyan/pen/BaqjRaK

四、会影响业务逻辑吗?

还有一点,有同学担心 CSS 只是视觉层面的,可能会影响业务逻辑。

确实,由于是伪元素渲染,页面上看不到任何数字,也就是无法直接通过 innerText 获取当前时间,但是,我们可以借助 getComputedStyle 来得到 CSS 变量

 getComputedStyle($0).getPropertyValue('--ms')

实时获取如下

所以通过 CSS 方式也是完全不影响业务逻辑的

五、兼容性和总结

由于在实现中用到了 CSS @property 特性,这是 CSS Houdini 的一部分,目前只有 Chrome 支持(可惜了

相关阅读

  • 档案数字化游学班——第三期上海站

  • 点击蓝字 · 关注我们档案数字化游学班——第三期上海站樱为你来,兰台人齐聚宝山 ——用数字档案引领现代治理和高效服务春风十里,美好如期。4月19日,中国档案管理培
  • 瑞典乌普萨拉大学吕智涵:构建真正的元宇宙

  • 随着电影《瞬息全宇宙》荣获奥斯卡金像奖七项大奖,“元宇宙”这个词再次吸引了观众们的注意。从2021年“元宇宙”开始变得火热到现在已经近两年时间,由于元宇宙这个词所代表的
  • 推动数字社会治理高质量发展

  •   党的二十大报告强调,要健全共建共治共享的社会治理制度,提升社会治理效能,并提出要加快建设数字中国。作为数字中国建设与社会治理的重要结合点,数字社会治理也在实践探索中
  • 数字检察赋能营商环境优化“走深走实”

  • 北仑检察院启动浙江自贸区宁波片区法治保障中心。4月14日,由北仑区检察院牵头,在浙江省检察院、宁波市检察院领导及60家行政机关、65家企业共同见证下,浙江自贸区宁波片区法治
  • 乐视子公司被执行7596万

  • 天眼查App显示,近日,乐视新媒体文化(天津)有限公司新增一则被执行人信息,执行标的7596万余元,执行法院为北京市朝阳区人民法院。该公司成立于2013年9月,法定代表人为朱鹏博,注册资本

热门文章

  • “复活”半年后 京东拍拍二手杀入公益事业

  • 京东拍拍二手“复活”半年后,杀入公益事业,试图让企业捐的赠品、家庭闲置品变成实实在在的“爱心”。 把“闲置品”变爱心 6月12日,“益心一益·守护梦想每一步”2018年四
  • 美国对华2000亿关税清单,到底影响有多大?

  • 1 今天A股大跌,上证最大跌幅超过2%。直接导火索是美国证实计划对华2000亿美元产品加征25%关税。 听起来,2000亿美元数目巨大,我们来算笔账。 2000亿美元,按现在人民币汇率

最新文章

  • 第四届工程生物创新大会将在深圳举办

  • 为进一步加强国内外合成生物学领域的交流合作,提高我国在合成生物学领域的国际地位,推动国内生物产业蓬勃发展,4月27至28日,第四届工程生物创新大会、第二届中国合成生物学学术
  • 【第2925期】纯 CSS 实现一个计时器

  • 前言去 JS 化实现计时器,其实通过这种案例蛮可以探索点。今日前端早读课文章由 @XboxYan 分享,公号:前端侦探授权。前端早读课:有用的文章,值得看第二遍正文从这开始~~CSS 现在可不
  • 为什么说前端监控系统离不开 RabbitMQ?

  • 前端监控系统是采集用户端的异常、性能、业务埋点等数据上报,在服务端做存储,并支持可视化分析的平台。用户量可能很大,采集的数据可能比较多,这时候服务端的并发压力会比较大,要
  • 联合更新 vol.15

  • 小提醒:这篇图文摒弃了之前的左右滑动的多图样式,不知道大家是否习惯,当然如果你喜欢现在的样式,记得点赞或者留言告知我最近一段时间没有更新谷歌版本,导致了不少版本的积压,还有
  • 【紧急预警】微信新出闪退Bug,全机型中招!

  • 上个月微信和QQ等业务曾出现崩溃状况,包括微信语音对话、朋友圈、微信支付,以及QQ文件传输、QQ空间和QQ邮箱在内的多个功能无法使用。没多久,腾讯将它定义为公司一级事故,并开出