用 animation-play-state 控制播放/暂停最直接,它只接受 running 和 paused 两个值,通过切换 class(如 .is-paused)比内联 style 更易维护;而 Element.animate() 的 play()/pause()/reverse() 仅适用于 JS 创建的动画,reverse() 会翻转 direction 并映射 currentTime。

用 animation-play-state 控制播放/暂停最直接
CSS 本身不提供 JS 那样的 play() / pause() 方法,但 animation-play-state 是唯一原生支持运行时切换播放状态的 CSS 属性。它只接受两个值:running(默认)和 paused。
常见错误是试图用 display: none 或 visibility: hidden 暂停动画——它们会中断动画进程,恢复时从头开始,不是真正“暂停”。
实操建议:
- 给动画元素设一个 class,比如
.is-paused,里面写animation-play-state: paused; - 用 JS 切换 class:
el.classList.toggle('is-paused'),比内联 style 更易维护 - 注意:该属性对
@keyframes中使用animation-direction: reverse无效——它只控制“是否动”,不改变方向
JS 中调用 animate() 的 play() / pause() / reverse()
只有通过 Element.animate() API 创建的动画才支持这些方法。原生 CSS animation 声明不暴露 Animation 对象,无法直接调用。
立即学习“前端免费学习笔记(深入)”;
典型使用场景:需要精确控制时间、动态修改关键帧、或响应用户拖拽/滚动等交互。
示例代码片段:
const anim = el.animate([
{ transform: 'translateX(0)' },
{ transform: 'translateX(200px)' }
], {
duration: 1000,
fill: 'forwards'
});
<p>// 暂停、播放、反向播放
anim.pause();
anim.play();
anim.reverse(); // 注意:reverse() 不重置 currentTime,只是翻转 direction 并继续播放关键点:
-
reverse()会把direction设为reverse,并把currentTime映射到反向时间轴(比如当前在 700ms,反向后就变成 300ms) - 调用
play()后若动画已结束且fill为forwards,需先anim.cancel()再animate()重建,否则无效 - 多个
animate()调用会覆盖前一个,旧 Animation 对象进入inactive状态
为什么 animation-direction: reverse 不能替代 reverse()
animation-direction: reverse 是声明式 CSS 属性,只在动画**启动时**生效;它不会让正在播放的动画“掉头”,也不会影响已运行中的 currentTime。
如果你希望点击一次按钮让动画来回走(比如呼吸效果),仅靠 CSS 无法实现——必须用 JS 控制 currentTime 或重建动画。
容易踩的坑:
- 误以为加了
animation-direction: reverse就能让播放中的动画倒放 → 实际毫无反应 - 用
el.style.animationDirection = 'reverse'触发重播,但没重置animationName或 duration → 浏览器可能忽略变更 - 想用 CSS 自定义属性(
--dir)配合animation-direction: var(--dir)动态切换 → 不合法,CSS 不允许变量用于该属性
兼容性与 fallback 处理要点
animation-play-state 在所有现代浏览器中都支持(包括 IE10+),但 Element.animate() 在 Safari 上直到 17.4 才完整支持 reverse(),iOS Safari 17.2 及更早版本调用会静默失败。
实操建议:
- 检测支持:
if ('animate' in Element.prototype),再判断anim.reverse是否为函数 - 不支持
reverse()时,可用anim.currentTime = anim.effect.getTiming().duration - anim.currentTime+anim.play()模拟(需手动处理fill和边界) - 避免在动画中混合使用 CSS
animation和 JSanimate()→ 容易因优先级冲突导致行为不可预测
真正难的不是调用某个方法,而是理解「动画实例」和「CSS 声明」是两套互不感知的系统。混用时,JS 控制的优先级永远高于 CSS,但一旦 JS 动画结束,CSS 声明又会悄悄接管——这个交接点最容易出 bug。



















