• 如何用纯 CSS 实现倒计时效果
  • 发布于 2个月前
  • 156 热度
    0 评论
在日常开发中,实现倒计时功能最先想到的是使用 JavaScript 定时器,随着 CSS 的发展,现代 CSS 被越来越多的浏览器所支持,本文将探索使用现代 CSS 的特性,实现倒计时效果。

一.核心知识点
实现倒计时的核心是通过 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) 函数被使用同样的参数调用了一样。

基础语法:
@property --property-name {
  syntax: "<color>";
  inherits: false;
  initial-value: #c0ffee;
}
浏览器兼容性:

1.2.CSS Counter
基本介绍:
1).counter-reset: counter-name start-value
主要用于创建或复位计数器。
counter-name:计数器的唯一标识符。
start-value:可选项,标识计数器的初始值。如果未指定,默认值为 0。
2).counter-increment: counter-name increment-value
主要用于增加或减少计数器的值
counter-name:要递增的计数器的标识符。
increment-value:要递增计数器的值。这是可选项,如果未指定,默认值为 1。
3).content: counter(counter-name, style)
要显示计数器的当前值,我们可以将 content 属性与 ::before 或 ::after 伪元素结合使用。content 属性使用以下语法显示计数器:

counter-name:要显示的计数器的标识符。
style:显示计数器值的样式。这是可选项,如果未指定,默认为十进制。
浏览器兼容性:

二.具体实现
2.1.实现页面框架
通过 html:5 和 div.countdown>svg.circle>(circle.circle-01[r=45]+circle.circle-02[r=45]) 快速创建页面及容器。在示例中除了实现倒计时的走秒效果,还通过增加 svg 元素来实现圆环进度效果,整体体验会更好。
<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 作为时间容器来显示倒计时。基础样式如下:
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显示。
&::after {
  --s: calc(var(--t)/1);
  counter-reset: s var(--s);
  content: "00:" counter(s, decimal-leading-zero);
}
2)CSS @property:
通过 CSS property 来实现属性动画。
@property --t {
  syntax: "<number>";
  initial-value: 10;
  inherits: true;
}
@property --s {
  syntax: "<integer>";
  initial-value: 0;
  inherits: true;
}
3)增加动画:
.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;
  }
}
三.效果预览

用户评论