animation-direction: alternate 必须搭配 animation-iteration-count: infinite 或大于1的值才生效,否则仅首轮正向播放即停止;它使奇数轮正向、偶数轮反向自然衔接,而 reverse 仅单次倒播且不循环。

animation-direction: alternate 必须搭配 infinite 或 >1 的 iteration-count
只写 animation-direction: alternate 不会看到交替效果——第 1 次永远正向播完就停了,方向切换只发生在第 2 次及以后。浏览器不会主动“多播一次”来让你看见反向。
常见错误是简写里漏掉循环次数:animation: slide 2s 等价于 animation-iteration-count: 1,alternate 完全不生效。
- 正确写法示例:
animation: slide 2s ease-in-out infinite alternate - 也可分开写:
animation-name: slide; animation-duration: 2s; animation-iteration-count: infinite; animation-direction: alternate - 若只需来回一次(去→回),用
animation-iteration-count: 2更精准,避免无限循环干扰调试
别用 animation-direction: reverse 实现“往返”,它不是 alternate
animation-direction: reverse 是单次倒播:从关键帧的 100% 状态开始,一路过渡到 0% 状态,然后停止或重复同一过程。它不会自动重置起点,也不会和上一轮衔接。
典型误用现象:
立即学习“前端免费学习笔记(深入)”;
- 元素“卡在起始位置不动”:因为 reverse 每轮都从 100% 开始,而你的元素初始态是 0%,第一帧就跳到 100% 值,再滑回来——如果没预留偏移,视觉上像闪一下又回原位
- 写了
infinite却只看到“反复闪退”,本质是每轮都在做同一件事:100% → 0% - 想实现“播完自动收起”,结果用了 reverse,动画结束停在 0%,但用户预期是回到原始布局态,而 reverse 并不保证这点
关键帧两端状态不一致会导致往返跳变
当 0% 和 100% 的样式值不同(比如 0% { transform: translateX(0); },100% { transform: translateX(100px); }),用 alternate 往返时,第 2 轮从 100px 开始往 0 移动,看起来是“回撤”,但第 3 轮又得从 0 重新出发——这本身没问题,但若中间帧缓动不对称(如只在正向用了 cubic-bezier(0.4, 0, 0.2, 1)),反向时浏览器会镜像时间函数,可能造成速度感突变。
更稳妥的做法:
- 让
0%和100%状态一致(例如都设transform: translateX(0)),变化集中在中间帧(如50%) - 避免依赖
animation-fill-mode: forwards,尤其当 0% 和 100% 不同时——它会强制保留最后一帧(即 100%)状态,导致第 2 轮反向开始前先跳回 0%,产生断层 - 真需要保持终点态,改用
animation-fill-mode: backwards或 JS 控制 class 切换
alternate 和 alternate-reverse 的第一帧差异极易被忽略
两者都交替,但第 1 次播放方向相反:alternate 第 1 次正向(0% → 100%),alternate-reverse 第 1 次就反向(100% → 0%)。这意味着用户第一眼看到的是“出发”还是“回撤”,完全取决于你选哪个。
实际影响:
- IE10+ 支持
alternate,但不支持alternate-reverse,老项目慎用后者 - 如果关键帧是
0% { opacity: 0; } → 100% { opacity: 1; },用alternate-reverse第一帧就是opacity: 1,元素直接显示再淡出——容易被当成加载异常 - 暂停后恢复,方向计数器不会重置:播到第 5 次正向时暂停,再 play,它继续播完正向,才切第 6 次反向;你无法靠暂停/恢复来“手动切方向”


















