steps()是css逐帧动画的timing function,必须配合transition或animation使用,适用于雪碧图、打字机等卡顿式切换场景,需注意帧数与steps参数匹配(n帧用steps(n-1))、起始/结束位置计算及浏览器兼容性。

steps() 函数必须配合 transition 或 animation 使用
单独写 steps(4) 不会动,它只是 timing function 的一种,得塞进 transition-timing-function 或 @keyframes 的 animation-timing-function 里。常见错误是只写了 steps(5) 却忘了绑定到属性变化上——比如想让背景位置跳变,但没配 transition: background-position 1s steps(5),自然静止不动。
使用场景很明确:需要卡顿式逐帧切换,比如雪碧图(sprite)动画、状态机 UI(如进度条分步高亮)、老式打字机效果(字符逐个出现)。它不插值,而是把整个动画过程切成 n 段,每段停留固定时间,跳到下一个关键帧。
-
steps(4, start):动画开始时立刻跳到第 1 帧(第 1 段起点),共跳 4 次,停在第 5 帧(即终点) -
steps(4, end)(默认):动画开始保持第 0 帧,第 1/4 时间点跳到第 1 帧,最后 1/4 时间点跳到第 4 帧并停留到结束 - 数值必须是正整数,
steps(3.5)无效,会被浏览器忽略或降为steps(3)
用 background-position 做雪碧图逐帧动画最稳妥
这是 steps() 最经典、兼容性最好的用法。前提是雪碧图横向排列、等宽等高,且总宽度 = 单帧宽 × 帧数。例如一张 800px 宽的图,含 8 帧,每帧 100px,则 background-position 需从 0 变到 -700px(注意:不是 -800px,因为最后一帧左边缘在 -700px 处)。
实操要点:
- 容器设固定宽高,
background-size设为实际图宽(如800px auto),避免缩放失真 - 动画用
@keyframes定义from { background-position: 0; } to { background-position: -700px; } -
animation中必须写steps(7, end)—— 注意是 7,不是 8,因为从第 0 帧到第 7 帧共 7 次跳跃才能播完 8 帧 - IE10+、Edge 12+、Chrome 23+、Firefox 16+ 均支持,无需前缀
transform translateX 配 steps 容易错位
用 transform: translateX() 做水平逐帧位移,看似简单,但极易因“起始偏移量”和“steps 数量”不匹配导致首尾帧缺失或重复。例如 4 张卡片排成一行,想每次滑 100% 宽度,共 3 次位移走完全部,却写了 steps(4),结果第 4 次跳完就超出了可视区。
关键判断逻辑:
- 若有 n 个状态(如 n 张图、n 个步骤),需 n−1 次跳跃完成全部切换
- 起始状态为第 0 帧,
to目标值应对应第 n−1 帧的偏移量(如translateX(-300%)表示滑过 3 个 100% 宽度) - 务必用
transform: translateX(calc(-100% * (n - 1)))这类计算,别手敲数字,否则改帧数时容易漏改 - 动画播放完若要重置,不能靠
animation-fill-mode: forwards硬留终态——它会卡在最后一跳后的位置,可能破坏交互;建议用 JS 监听animationend后手动归位
steps 动画暂停/跳转时行为不可控
steps() 是离散函数,不支持中间态。调用 element.style.animationPlayState = 'paused' 会停在当前帧,但无法保证停在哪一帧——取决于暂停时刻落在哪个 step 区间内,不同浏览器甚至同一浏览器多次运行都可能不同。
如果业务需要精确控制到某一帧(比如用户点击“下一步”就强制跳到第 3 帧),不要依赖 animation 播放过程,而应:
- 用 CSS 类切换 +
background-position或transform的具体值(如background-position: -200px) - 或用 JS 计算目标帧偏移量,直接赋值,再触发动画(用
getComputedStyle强制重排后加 class) - 避免在
@keyframes中混用steps()和线性缓动,浏览器会取第一个合法 timing function,后面那个被丢弃
真正难的不是写对第一帧,而是当帧数变多、需要循环、要响应用户操作时,step 边界和状态同步很容易脱节。动手前先画个时间轴,标出每一跳发生的时刻和位置,比直接敲代码更省时间。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











