本文翻译自 How to Make a CSS Timer,作者:PREETHI SAM, 略有删改。

有时候我们需要再网站中使用计时器。比如下单购物成功后增加倒计时回到首页;或者一些时间管理工具(番茄工作法),当遇到这些情况时,我会毫不犹豫地使用JavaScript,因为它可能是处理这类事情的更强大的工具。

然而在某些场景下 CSS 替代品也同样有趣和高效。现在的电子邮件客户端具有很强的 CSS 能力,但却永远无法运行 JavaScript,因此这种情况或许可以成为一种有趣的增强功能。

让我们来看看如何制作一个CSS定时器。我们会用一些现代的CSS技术来做。主要需要用到以下CSS能力:

  • CSS Counters
  • @property
  • 伪元素
  • @keyframes

下图是我们要实现的演示效果,鼠标移入开启倒计时:

我们的CSS定时器主要有三个要求:

  • 一个能从5减到0的数
  • 一种计时五秒的方法,并在每一秒中递减数字
  • 一种在页面上显示递减数字的方法

数量

对于我们的第一个需求,一个可更新的数字,我们使用 @property 创建一个自定义属性,该属性将保存一个 <integer> 类型的值。

注意:integer 可以是零,也可以是正整数或负整数。如果你想要小数点的数字,使用 number,它会保存一个真实的数字。

@property --n {
  syntax: "<integer>";
  inherits: false;
  initial-value: 0;
}

计数

对于秒数变化减少数字的效果,我们使用@keyframes动画实现。

.timer:hover::after {
  animation: 5s linear count;
}

@keyframes count {
  from { --n: 5; }
  to   { --n: 0; }
}

当我们为特定的值类型注册一个自定义属性时,例如<integer><percentage><color>,浏览器知道该属性是为处理该特定类型的值而创建的。所以浏览器可以自信地在未来更新自定义属性的值,在动画中也是如此。

这就是为什么我们的属性--n可以在动画中从5到0,并且由于动画设置为5秒,因此实际上是在5秒的时间内从5到0的计数。于是计时器上场了。

现在还有一个问题就是如何将计数的数字展示到页面上。这里将动画分配给了一个伪元素,你可能已经想到使用伪元素的 content

显示

CSS属性content可以显示我们自己尚未添加到HTML中的内容。我们通常将此属性用于各种用途,因为它接受各种值:图像,字符串,计数器,引号,甚至属性值。不过它不能直接接受数字。因此我们将通过计数器传入数字 --n

计数器可以通过 counter-resetcounter-increment 进行设置。我们将使用 counter-reset。这个属性的值是一个计数器名称和一个整数。由于 counter-reset 尚不能正确处理作为整数的 CSS 变量或自定义属性,但可以接受 calc(),因此 calc() 函数成为我们的关键实现,我们将通过它传递 –-n

.timer:hover::after {
  animation: 5s linear count;
  animation-fill-mode: forwards; 
  counter-reset: n calc(0 + var(--n));
  content: counter(n);
}
  • 我们的动画数字--n首先被传递到 calc()
  • calc()然后被传递到counter()
  • counter()依次传递给content,最后在页面上呈现--n

剩下的由浏览器来处理。它知道--n是一个整数。浏览器会在5秒内将此整数从5更改为0。

在动画结束时使用animation-fill-mode: forwards属性防止计时器立即恢复到初始的--n值0。

在设计方面,你可以进行递增或递减,或者改变其外观,或者你也可以将其与其他典型的加载器或进度条设计结合起来。

CSS 自定义属性也可以在 JavaScript 中设置和更新。因此,如果你希望在某个时候能够在 JavaScript 中更新这些属性,就像更新其他 CSS 属性一样,你可以使用 setProperty() 函数来实现。如果你想在 JavaScript 中创建一个新的自定义属性,可以使用 registerProperty() 函数。相反地如果你希望让 JavaScript 知道 CSS 动画已经完成,你可以监听 animationend 事件。

总结

这篇文章展示了如何使用CSS技术,包括CSS计数器、@property规则、伪元素和@keyframes动画,来创建一个纯CSS的计时器效果。这种方法在不支持JavaScript的环境中非常有用,如电子邮件中,有兴趣的可以尝试看看~

端午节快乐~ 公众号回复 20240607 查看源代码


看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~

专注前端开发,分享前端相关技术干货,公众号:南城大前端(ID: nanchengfe)