数字滚动动画核心是用transform: translatey()切换垂直堆叠的0–9数字列表,配合data-current属性与css属性选择器驱动翻页,js仅负责更新属性值,确保硬件加速与像素级对齐。

数字滚动动画的核心是 CSS transform: translateY() + 数字列表定位
纯 CSS 实现“翻页式”数字时钟(如 12:05:59 → 12:06:00 的秒位从 9 翻到 0),关键不是逐帧动画,而是用一列预排数字(0–9)垂直堆叠,通过 transform: translateY() 快速切换可见行。浏览器原生支持该变换的硬件加速,无 JS 也能流畅运行。
常见错误是直接对数字文本做 animation: rotateX() —— CSS3 的 3D transform 在部分移动端不触发硬件加速,且无法精准控制“翻页”停顿感;更糟的是用 opacity 切换多个 span,会触发重排+重绘,卡顿明显。
- 每个数字位需包裹在一个固定高宽的容器(如
.digit),设overflow: hidden - 内部用
<ul class="digits-list"></ul>垂直排列 10 个<li>,每个含一个数字(0–9) - 通过改变
ul的transform: translateY(-Npx)(N = 单个数字高度 × 目标数字值)来“拉动”列表 - 过渡用
transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94)模拟惯性翻转,避免线性生硬
如何用 @keyframes 配合 data-current 属性驱动翻页?
纯 CSS 无法读取实时时间,所以必须由外部(比如轻量 JS)仅负责更新 data-current 属性值,CSS 基于该属性匹配伪类触发动画。这是“纯 CSS 动画”但“非纯 CSS 时间驱动”的合理分工。
错误做法是把所有逻辑塞进 CSS:例如用 :nth-child() 模拟计数器——它静态不可变,无法响应时间变化;或滥用 counter-increment,它不触发重绘,根本不会动。
- HTML 结构示例:
<div class="clock-digit" data-current="7"><ul> <li>0</li>...<li>9</li> </ul></div> - CSS 中用属性选择器匹配:
[data-current="0"] .digits-list { transform: translateY(0); }、[data-current="1"] .digits-list { transform: translateY(-2rem); }(假设单数字高 2rem) - 为每个数字值写一组规则(共 10 组),配合
transition实现平滑位移 - JS 只需每秒执行一次:
digitEl.setAttribute('data-current', newSec % 10),其余全交由 CSS
各数字位宽度不一致(如 1 vs 8)导致翻页错位怎么办?
数字“1”默认比“8”窄,若容器用 text-align: center 且未统一字体度量,翻页时会出现左右晃动,破坏“机械翻页”观感。这不是动画问题,而是排版基线没锁死。
典型表现:秒位从 1 翻到 2 时,整个数字块轻微右移;使用等宽字体后仍抖动——根源是不同数字的 vertical-align 和 line-height 在行内布局中实际占据高度不一致。
- 强制使用等宽字体:
font-family: 'Courier New', monospace;,并设font-variant-numeric: tabular-nums;(确保数字宽度严格一致) - 容器设
display: grid;+place-items: center;替代text-align,消除行内元素基线干扰 - 每个
li设固定height和line-height,且li { margin: 0; padding: 0; },避免盒模型差异 - 测试时用
outline: 1px solid red叠加查看各数字实际占位框是否完全重合
移动端 Safari 和旧版 Chrome 对 transform 过渡的兼容性坑
iOS 15.4 之前,Safari 对 transform 的 cubic-bezier() 支持不全,某些缓动函数会导致动画跳帧或直接失效;Android Chrome 80–90 有 transform 在 position: absolute 元素上偶发不触发硬件加速的问题。
不是所有“看起来能动”的 CSS 就真在真实设备上稳——尤其当多个数字位同时翻页(如 59→00),GPU 负载突增时,弱设备容易掉帧甚至回退到软件渲染。
- 务必加
will-change: transform;到.digits-list,提前提示浏览器该元素将频繁变换 - 避免在
transform同时修改width或height,这会强制触发重排 - Safari 兼容方案:用
transition-timing-function: ease-in-out;替代复杂贝塞尔曲线,实测 iOS 14+ 稳定 - 真机测试必做:开启 iOS「设置 > 辅助功能 > 动态效果 > 减少动态效果」后,确认动画仍可读(此时系统会禁用部分 transform 动画,需 fallback 到静止数字)
真正难的不是写出能翻的动画,而是让 0–9 十个数字在任意屏幕缩放、任意系统字体设置、任意辅助功能开关下,都保持像素级对齐和帧率稳定。这点靠 CSS alone 无法兜底,必须接受 JS 做最小必要干预(仅设属性),其余全部交给渲染引擎。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











