在日常开发中,实现倒计时功能最先想到的是使用 JavaScript 定时器,随着 CSS 的发展,现代 CSS 被越来越多的浏览器所支持,本文将探索使用现代 CSS 的特性,实现倒计时效果。
1.核心知识点
实现倒计时的核心是通过 CSS Animation 实现伪元素的内容变化。用到的核心知识点包括 CSS @property 和 CSS Counter。
1.1.CSS @property
引用 MDN 的定义:
@property CSS at-rule 是 CSS Houdini API 的一部分,它允许开发者显式地定义他们的CSS 自定义属性, 允许进行属性类型检查、设定默认值以及定义该自定义属性是否可以被继承。
@property 规则提供了一个直接在样式表中注册自定义属性的方式,而无需运行任何 JS 代码。有效的 @property 规则会注册一个自定义属性,就像 CSS.registerProperty (en-US) 函数被使用同样的参数调用了一样。
基础语法:
css
@property --property-name {
syntax: "<color>";
inherits: false;
initial-value: #c0ffee;
}
浏览器兼容性:
1.2.CSS Counter
基本介绍:
- counter-reset: counter-name start-value
主要用于创建或复位计数器。
- counter-name:计数器的唯一标识符。
- start-value:可选项,标识计数器的初始值。如果未指定,默认值为 0。
- counter-increment: counter-name increment-value
主要用于增加或减少计数器的值
- counter-name:要递增的计数器的标识符。
- increment-value:要递增计数器的值。这是可选项,如果未指定,默认值为 1。
- content: counter(counter-name, style)
要显示计数器的当前值,我们可以将 content 属性与 ::before 或 ::after 伪元素结合使用。content 属性使用以下语法显示计数器:
- counter-name:要显示的计数器的标识符。
- style:显示计数器值的样式。这是可选项,如果未指定,默认为十进制。
浏览器兼容性:
2.具体实现
2.1.实现页面框架
通过 html:5
和 div.countdown>svg.circle>(circle.circle-01[r=45]+circle.circle-02[r=45])
快速创建页面及容器。在示例中除了实现倒计时的走秒效果,还通过增加 svg
元素来实现圆环进度效果,整体体验会更好。
html
<div class="countdown">
<svg viewBox="-50 -50 100 100" stroke-width="10" class="circle">
<circle r="45" class="circle-01"></circle>
<circle r="45" class="circle-02" pathLength="1"></circle>
</svg>
</div>
2.2.增加基础样式
通过给 svg 增加 stroke
、stroke-lineup
、stroke-dasharray
等样式来实现圆环效果,通过增加伪元素 ::after
作为时间容器来显示倒计时。基础样式如下:
css
body {
display: grid;
place-items: center;
height: 100vh;
background-color: #282c34;
}
.countdown {
display: grid;
width: 20em;
height: 20em;
.circle {
grid-column: 1;
grid-row: 1;
.circle-01 {
fill: none;
stroke: #fff;
}
.circle-02 {
--t: 2;
--k: calc(var(--t)/20);
fill: none;
transform: rotate(-90deg);
stroke-linecap: round;
stroke: color-mix(in hsl shorter hue, #8a9b0f calc(var(--k)*100%), #940a3d);
stroke-dasharray: var(--k) 1;
}
}
&::after {
grid-column: 1;
grid-row: 1;
place-self: center;
font-size: 5em;
color: #fff;
content: "00:19";
}
}
初始效果如下:
2.3.增加动画
通过基础示例我们可以看到,要想实现倒计时效果,::after
元素的 content
属性值需要和 --t
变量关联上。
1)CSS Counter:
通过 CSS Counter 实现秒数打印,注意我们通过给 counter 增加 decimal-leading-zero
了以实现前导 0显示。
css
&::after {
--s: calc(var(--t)/1);
counter-reset: s var(--s);
content: "00:" counter(s, decimal-leading-zero);
}
2)CSS @property:
通过 CSS property 来实现属性动画。
css
@property --t {
syntax: "<number>";
initial-value: 10;
inherits: true;
}
@property --s {
syntax: "<integer>";
initial-value: 0;
inherits: true;
}
3)增加动画:
css
.countdown {
animation: linear 10s linear infinite;
.circle {
.circle-02 {
--k: calc(var(--t)/10);
stroke: color-mix(in hsl shorter hue, #8a9b0f calc(var(--k)*100%), #940a3d);
stroke-dasharray: var(--k) 1;
}
}
}
@keyframes linear {
to {
--t: 0;
}
}
4)效果预览: