steps() 是 timing-function,需配合 animation 或 transition 使用;卡顿主因是帧数与 steps(n) 不匹配、background-size 未设或 background-position 位移量错误;steps(n, start) 首帧瞬显,steps(n, end) 首帧延时 1/n 时长。

steps() 不是动画函数,它是 timing-function,必须配合 animation 或 transition 使用;直接写 animation-timing-function: steps() 才能触发逐帧效果,单独调用它不会动。
为什么 steps() 动画卡顿或跳帧?
常见原因是精灵图帧数与 steps(n) 的 n 值不匹配,或未正确设置 background-size 和 background-position 的变化范围。
-
steps(4, end)表示把整个动画时长均分为 4 段,每段结束时跳到下一帧(共显示 4 帧);若精灵图有 8 帧却写steps(4),就会每两帧合并成一次跳变 - 必须让
background-position的总位移量 = 单帧宽度 × (帧数 − 1),例如 8 帧横向排列、每帧 64px,则background-position应从0变到-448px(即-64px × 7) - 漏设
background-size会导致背景图被拉伸/压缩,使background-position计算偏移失效
steps(n, start) 和 steps(n, end) 的行为差异
区别在于第一帧是否立即显示,这直接影响“启动感”——复古游戏常需无延迟起始,此时选 start 更贴切。
-
steps(6, end):动画开始后等待 1/6 时长才显示第 2 帧,第 1 帧持续整个第一段时长 -
steps(6, start):第 1 帧在 t=0 瞬间出现,之后每过 1/6 时长跳一帧,共完成 6 次跳变(显示 6 帧) - 若用
@keyframes写了0% { background-position: 0 }和100% { background-position: -384px },且共 7 帧,则应配steps(6, start),否则最后一帧来不及显示
完整可运行的逐帧动画 CSS 片段
假设一个横向排列的 5 帧精灵图,每帧 100×100px,总图宽 500px:
立即学习“前端免费学习笔记(深入)”;
div.sprite {
width: 100px;
height: 100px;
background-image: url('sprite.png');
background-size: 500px 100px; /* 必须显式声明 */
background-position: 0 0;
animation: frame-animation 0.5s steps(4, start) infinite;
}
<p>@keyframes frame-animation {
0% { background-position: 0 0; }
100% { background-position: -400px 0; } /<em> 4 × 100px 位移 </em>/
}注意:steps(4) 对应 5 帧(0→1→2→3→4),因为位移有 4 次变化;animation-duration 越小,帧率越高,但低于 0.08s 可能因渲染精度丢失帧。
容易被忽略的是:background-position 的插值类型默认是「平滑过渡」,而 steps() 强制覆盖为离散跳变——这个覆盖只对当前属性生效,如果同时 animating opacity,它仍会缓动,除非也给它加 steps()。


















