animation-iteration-count: infinite 是唯一可靠方案,必须配合 animation-duration(≥0.5s)和合适的 timing-function;首尾关键帧状态需一致,alternate 模式下注意反向结束语义。

animation-iteration-count: infinite 是唯一可靠方案
想让 CSS 动画一直动下去,animation-iteration-count: infinite 是标准且兼容性最好的写法。其他方式(比如用 @keyframes 末尾跳回起点、或靠 JS 反复触发)要么不生效,要么引入额外复杂度,还可能破坏动画时序。
这个属性值是关键字,不能写成字符串 "infinite",也不能用数字替代——写成 999 看似“够用”,但本质仍是有限次,且可能在长周期动画中提前终止。
必须配合 animation-duration 和 animation-timing-function 才能感知循环
只设 infinite 不代表你就能看到“循环效果”——如果 animation-duration 太长、或 animation-timing-function 是 steps(1) 这类离散函数,动画可能卡在某一帧不动,误以为没循环。
-
animation-duration至少设为0.5s以上,才能肉眼识别重复 - 避免用
animation-timing-function: step-end做渐变类动画,它容易让最后一帧“悬停”,掩盖循环行为 - 若需无缝衔接,关键帧首尾状态必须一致(例如
transform: translateX(0)开头和结尾都要有)
animation-direction: alternate + infinite 会产生反向播放
很多人想实现“往复滑动”,直接加 animation-direction: alternate,却发现第二次播放是从终点倒着来——这是预期行为,不是 bug。但要注意:
立即学习“前端免费学习笔记(深入)”;
- 此时动画总时长仍是单次
animation-duration,不是两倍 -
@keyframes中定义的 0% → 100% 会被正向执行一次,再反向执行一次(即 100% → 0%),所以中间状态(如 50%)会经过两次 - 若同时用了
animation-fill-mode: forwards,它只保留最后一次迭代结束时的状态,而alternate的最后一次是“反向结束”,可能导致最终样式与预期不符
不要用 animation-play-state 暂停后手动重启来模拟循环
有人试图用 JS 控制 animation-play-state: paused 再切回 running 来“重置循环”,这会导致两个问题:
- 动画时间轴不会重置,
animation-delay不再生效,暂停后再播会立刻接上原进度 - 反复 toggle play-state 可能引发渲染抖动,尤其在低端设备上
- 真正需要“重置”的场景(比如用户交互触发新起始点),应该用
animation-name: none瞬间清空,再设回原 name,强制浏览器重建动画实例
element.style.animationName = 'none';
setTimeout(() => {
element.style.animationName = 'slide-in';
}, 0);
无限循环本身很简单,难的是让它在各种 timing function、direction、fill-mode 组合下依然表现可控——最易忽略的是关键帧首尾状态是否真正一致,以及 alternate 模式下“最后一次迭代”的语义到底是正向还是反向结束。










