现代CSS:纯 CSS 实现倒计时效果

在日常开发中,实现倒计时功能最先想到的是使用 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

基本介绍:

  1. counter-reset: counter-name start-value

主要用于创建或复位计数器。

  • counter-name:计数器的唯一标识符。
  • start-value:可选项,标识计数器的初始值。如果未指定,默认值为 0。
  1. counter-increment: counter-name increment-value

主要用于增加或减少计数器的值

  • counter-name:要递增的计数器的标识符。
  • increment-value:要递增计数器的值。这是可选项,如果未指定,默认值为 1。
  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)效果预览:

相关推荐
JudithHuang10 分钟前
React 常用 Hooks
前端·react.js·前端框架
sycmancia1 小时前
Qml——Window元素使用
前端
每天都好困1 小时前
03 AR 投影与误差修正:把地图上的点贴到视频画面上
前端
每天都好困1 小时前
04 地图图层封装:像管理 Photoshop 图层一样管理地图元素
前端
去伪存真2 小时前
构建你的第一个 DevOps AI Agent:自动化捕获、分析并修复 CI 故障
前端·agent
niucloud-admin2 小时前
JAVA V6 多商户商城 开发文档——手机端前端
java·开发语言·前端
skywalk81632 小时前
deepseekharness在对话中,有四种模式,分别是极简、PTC、创造和标准模式,每种模式下挂载的插件、skill等数量不一样
前端·人工智能·实践
愛芳芳2 小时前
element-plus+vite+vue3+pinpa+mock+typeScript搭建经典的电商管理后台
前端·javascript·typescript
liangshanbo12153 小时前
面试题:常见的前端构建工具有哪些?分别适用于什么场景?
前端
linux_cfan3 小时前
videojs v10 源代码系列解读:30 · `SerialRunner` 与 `ConcurrentRunner`
前端