css动画如何实现无限循环_css动画循环属性详解

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

animation-iteration-count: infinite 是唯一可靠方案

想让 CSS 动画一直动下去,anima

tion-iteration-count: infinite 是标准且兼容性最好的写法。其他方式(比如用 @keyframes 末尾跳回起点、或靠 JS 反复触发)要么不生效,要么引入额外复杂度,还可能破坏动画时序。

这个属性值是关键字,不能写成字符串 "infinite",也不能用数字替代——写成 999 看似“够用”,但本质仍是有限次,且可能在长周期动画中提前终止。

必须配合 animation-duration 和 animation-timing-function 才能感知循环

只设 infinite 不代表你就能看到“循环效果”——如果 animation-duration 太长、或 animation-timing-functionsteps(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 模式下“最后一次迭代”的语义到底是正向还是反向结束。