CSS 动画迭代间添加暂停:正确实现循环动画的间隔控制

`animation-delay` 仅作用于动画首次启动前,无法控制每次循环之间的间隔;要实现在每轮动画结束后暂停一段时间再开始下一轮,需通过延长动画周期并合理分配关键帧时间占比来模拟“停顿”效果。

在 CSS 中,animation-delay 的设计初衷是定义动画第一次播放前的等待时间,而非两次迭代之间的间隔。因此,即使你设置 animation-delay: 1s 并配合 animation-iteration-count: infinite,动画仍会无缝循环——第 2 次、第 3 次……迭代均不会插入额外延迟。

✅ 正确解法:将“停顿”作为动画周期的一部分
即:拉长 animation-duration,并在 @keyframes 中,用关键帧(如 90% → 100%)让元素保持静止状态,从而视觉上形成“播放 → 暂停 → 播放”的节奏。

以你的 .fa-shake 为例,原动画时长为 1s,无停顿。若希望每次抖动后暂停 0.5s,可将总时长设为 1.5s,并调整关键帧分布:

.fa-shake {
  animation-name: fa-shake;
  animation-duration: 1.5s;           /* 总周期 = 动画时长 + 暂停时长 */
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  animation-fill-mode: forwards;
  width: 150px;
  height: auto;
}

@keyframes fa-shake {
  /* 0% → 66.7%:完成完整抖动动画(原1s映射为1s/1.5s ≈ 66.7%) */
  0%, 6.7%, 13.3%, 20%, 26.7%, 33.3%, 40%, 46.7%, 53.3%, 60%, 66.7% {
    transform: rotate(0deg);
  }
  6.7%, 20%, 33.3%, 46.7%, 60% {
    transform: rotate(10deg);
  }
  13.3%, 26.7%, 40%, 53.3% {
    transform: rotate(-20deg);
  }

  /* 66.7% → 100%:静止暂停(0.5s 占比 = 0.5 / 1.5 ≈ 33.3%) */
  66.7%, 100% {
    transform: rotate(0deg); /* 保持起始态,视觉暂停 */
  }
}

? 关键技巧:

  • 计算比例:若原动画耗时 T₁,期望暂停 T₂,则新 animation-duration = T₁ + T₂,暂停段应覆盖 (T₂ / (T₁ + T₂)) × 100% 的关键帧区间;
  • 使用 animation-fill-mode: forwards 可确保最后一帧状态被保留(虽本例中 0% 和 100% 相同,但增强健壮性);
  • 避免在 0% 和 100% 同时定义不同状态,否则可能引发意外跳变。

⚠️ 注意事项:

  • 不要依赖 animation-delay 实现循环间隔——它对后续迭代完全无效;
  • 若需复杂节奏(如渐进暂停、多阶段延迟),建议改用 JavaScript 控制 animation-play-state 或使用 @property + transition(现代浏览器);
  • 所有关键帧百分比必须严格递增且覆盖 0% 和 100%,否则动画行为不可预测。

通过将暂停“内化”为动画逻辑的一部分,你既能保持纯 CSS 实现的简洁性,又能精准控制每一次迭代间的呼吸感。