css单选radio按钮样式css多选框checkbox样式css响应式汉堡菜单(左滑、抽屉)css实现遮罩层弹出效果一组好看的css按钮效果(6种)css实现select下拉选择框css实现选项卡功能css实现下拉菜单css按钮样式代码(16种)css实现手风琴效果css图片轮播效果css进度条样式css实现侧边栏菜单css加载动画css背景动画效果css开关按钮样式(18种)css炫酷的圆形菜单css提示tooltip效果css手风琴_好看的Gallery伸缩效果css表格样式css分段控件导航栏css折角效果css粒子背景动画效果css进度圆圈连线css响应式分页样式代码css各种天气样式动画图标css层叠卡片滑出特效css下拉Dropdown菜单css圆圈按钮tip提示特效css和svg圆圈进度样式代码css动画404页面代码css爱心跳动动画代码css绘制逼真玻璃球效果css模拟开关灯特效创意css网格布局带动画效果css星级打分radio五角星css卡片悬浮翻转特效div上下浮动纯css动画css时间轴样式(timeLine)css文字循环翻滚动画效果css输入框动效css鼠标悬停缩放比例效果css模糊背景毛玻璃效果css实现小球循环跳动动画css实现标签样式Tagscss进度条阴影动画css绘制的小鸟css svg按钮冒泡动画特效css svg蓝色波浪动画特效css创意svg菜单栏水滴动画css文字进度条的实现CSS实现内容折叠/展开效果CSS3手机充电特效css实现鼠标点击拖拽效果CSS实现一个计时器纯CSS渐变绘制 Chrome 图标CSS 渐变来实现波浪动画

CSS实现一个计时器

源码

<h1>css 计时器</h1>
<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>
<style>
html,
body {
margin: 0;
height: 100%;
display: flex;
justify-content: center;
flex-direction: column;
gap: 15px;
align-items: center;
background: aliceblue;
}
@property --m {
syntax: '<integer>';
inherits: false;
initial-value: 0;
}
@property --s {
syntax: '<integer>';
inherits: false;
initial-value: 0;
}
@property --ms {
syntax: '<integer>';
inherits: false;
initial-value: 0;
}
.counter {
display: grid;
gap: 10px;
grid-template-areas:"clock clock" "start reset"
}
.clock {
grid-area: clock;
text-align: center;
font-size: 60px;
padding: .2em .5em;
border: 5px solid rgba(255, 255, 255, .3);
font-family: monospace;
background: #3a3a3a;
color: #fff;
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);
animation-play-state: paused;
}
.clock::before {
content: counter(minitus, decimal-leading-zero) ':' counter(seconds, decimal-leading-zero) ':' counter(ms, decimal-leading-zero);
text-shadow: 3px 3px 3px black;
}
.btn {
text-align: center;
padding: .5em;
font-size: 24px;
background-color: royalblue;
color: #fff;
grid-area: start;
user-select: none;
cursor: pointer;
transition: .2s;
}
.btn:hover {
filter: brightness(1.1);
}
.reset {
grid-area: reset;
background-color: #F44336;
}
.start::before {
content: '开始';
}
:checked~.clock {
animation-play-state: running;
}
:checked~.start::before {
content: '暂停';
}
:checked~.reset {
opacity: .65;
pointer-events: none;
}
.reset:active+.clock {
animation: none;
}
@keyframes minitus {
to {
--m: 59
}
}
@keyframes seconds {
to {
--s: 59
}
}
@keyframes ms {
to {
--ms: 99
}
}
</style>

兼容性

由于在实现中用到了CSS @property特性,这是CSS Houdini的一部分,目前只有 Chrome 支持。让人惊奇的是,Safari居然在前不久也支持了这个特性,未来可期。

会影响业务逻辑吗?

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

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

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

总结实现要点

  1. CSS 现在很强大,不仅仅只是样式,还能做很多交互
  2. CSS @property 可以使CSS变量支持动画
  3. 数字时钟的变化其实是一个CSS变量不断递增循环的动画
  4. CSS 点击操作状态可以通过:checked控制
  5. Grid 布局可以很方便的控制各个元素的位置
  6. 计时器开始和暂停其实就是动画的运行和暂停
  7. 直接将动画取消就相当于重置了整个动画
来源:https://runjs.work/projects/6d3305ab2de14840


链接: https://www.fly63.com/course/33_1629