先记住这个答案
reverse 让动画每一轮都倒着播,从 to(或 100%)走到 from(或 0%),方向始终是反的。alternate 是奇数轮正向、偶数轮反向,来回交替。两者最大的区别在于 reverse 是恒定的反方向,而 alternate 的方向取决于当前是第几轮。另外 reverse 会把缓动曲线也翻转,ease-in 视觉上变成减速效果。
reverse每轮都倒着播alternate奇偶轮交替方向reverse同时反转缓动曲线- 只循环一次时
alternate等同normal
四种值的播放顺序对比
animation-direction 一共有四个取值。用同一个关键帧搭配不同值,就能直观看到区别。
animation-directionCSS@keyframes fade {
from { opacity: 1; }
to { opacity: 0; }
}
/* 每轮 1 → 0,正向播放 */
.a { animation: fade 1s normal forwards; }
/* 每轮 0 → 1,反向播放,看起来像淡入 */
.b { animation: fade 1s reverse forwards; }
/* 第一轮 1→0,第二轮 0→1,循环交替 */
.c { animation: fade 1s alternate 2 forwards; }
/* 第一轮 0→1,第二轮 1→0,反向开始交替 */
.d { animation: fade 1s alternate-reverse 2 forwards; }.a 正常淡出,.b 反着来变成淡入。.c 先淡出再淡入,两轮之后停在透明。.d 先淡入再淡出,两轮之后停在不透明。注意 .c 和 .d 都设了 animation-iteration-count: 2,只有一轮的话 alternate 和 normal 没区别。
alternate-reverse 可以理解成"先走一遍 reverse,再走一遍 normal",不需要单独记——就是 alternate 的镜像版本。
reverse 对缓动曲线的影响
reverse 不只是翻转关键帧的起终点,缓动曲线也一起翻转了。比如原本写了 animation-timing-function: ease-in,正向播放时动画开头慢、结尾快。加了 reverse 之后,视觉上变成开头快、结尾慢——和 ease-out 的效果一样。
这个行为在做弹跳或回弹动画时很有用。你可以只写一组 ease-in 关键帧,然后用 alternate 让返回时自动变成 ease-out 的效果,不用再写两套缓动。
alternate 在偶数轮反向播放时也有同样的缓动翻转。所以一个 alternate 动画的正向轮是 ease-in,反向轮自动变成 ease-out,视觉上非常自然。
容易答错的地方
- 以为
alternate只设一轮就能看到交替效果 alternate的第一轮和normal完全一样,要到第二轮才反向。如果animation-iteration-count是默认的 1,alternate就等于normal。至少要设成 2 或者infinite才有交替的视觉效果。- 以为
reverse只翻转方向,缓动不变 - 方向和缓动是一起翻转的。原本的
ease-in加了reverse后视觉上变成ease-out。如果忽略这一点,动画的加速减速节奏会和预期不同。
面试官还会怎么问?
animation-fill-mode: backwards 搭配 reverse 时,动画开始前显示哪一帧?
backwards 让元素在动画开始前就应用第一帧的样式。正向播放时第一帧是 from,但 reverse 下第一帧变成了 to。所以 reverse 加 backwards 时,动画开始前元素会显示 to 的样式。
alternate 和手动写两段关键帧有什么区别?
alternate 自动翻转缓动曲线,视觉上更平滑。手动写两段关键帧可以让去和回走不同的路径或不同的缓动,灵活度更高但代码量也多。简单的来回效果用 alternate,复杂的非对称路径用手写。
animation-direction 会影响 animationiteration 事件吗?
不会。不管方向怎么设,每完成一轮浏览器都会触发一次 animationiteration 事件。reverse 下每轮走完也触发,alternate 下正向轮和反向轮结束时也各触发一次。事件只关心轮次,不关心方向。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。