animation-play-state: paused 可暂停 css 动画,但需显式声明初始状态 running,否则 safari 等浏览器可能不生效;hover 暂停需先定义 animation-play-state: running,多个动画会同时暂停,js 控制更可靠且需注意属性名和值类型。

鼠标悬停暂停 CSS 动画,animation-play-state: paused 能用,但必须显式声明初始状态,否则 Safari 等浏览器可能无反应。
hover 暂停必须先写 animation-play-state: running
很多人直接写 .box:hover { animation-play-state: paused; },结果在旧版 Safari 或某些移动端 WebView 中不生效。根本原因是:如果元素的原始样式里没声明 animation-play-state,浏览器会按默认值 running 处理,但部分引擎对 hover 切换这个“隐式默认 → 显式 paused”的过程不触发重绘。
正确写法是显式初始化:
.marquee {
animation: scroll 8s linear infinite;
animation-play-state: running; /* 必须写这行 */
}
.marquee:hover {
animation-play-state: paused;
}
- 不写
animation-play-state: running,等于把控制权交给浏览器默认逻辑,不可靠 -
animation-fill-mode: forwards不影响 hover 暂停逻辑,但暂停后元素仍停留在当前帧,恢复时继续播放(不是重播) - 该属性不支持
transition,不能加淡入淡出效果——设了也没动画过渡
多个动画同时存在时,animation-play-state 会一起暂停
一个元素若声明了多个动画,比如 animation: fade 2s, spin 1.5s infinite;,那么 :hover { animation-play-state: paused; } 会让两个都停。CSS 没有“只停 fade 不停 spin”的语法。
如果你需要独立控制:
- 拆 DOM:把
fade和spin分到两个子元素上,各自绑定动画 - 改用 JS:
el.getAnimations().find(a => a.effect?.getTarget() === el && a.animationName === 'fade')?.pause()(注意兼容性,getAnimations()在 Safari 16.4+ 才稳定) - 别指望逗号分隔的
animation-play-state: paused, running—— 这个语法虽存在,但仅适用于内联 style 设置,且需和animation值严格顺序对应;CSS 文件中用它极易出错,不推荐
JS 动态控制比 class 切换更直接,但要注意命名和值类型
用 JS 改 style.animationPlayState 是最干脆的方式,不需要维护 class、也不怕层叠干扰:
const el = document.querySelector('.loader');
el.style.animationPlayState = 'paused'; // ✅ 正确
el.style.animationPlayState = 'running'; // ✅ 恢复
el.style.animationPlayState = ''; // ❌ 错误:会退回到 CSS 规则值,行为不确定
- JS 属性名是驼峰式
animationPlayState,不是短横线animation-play-state,写错会静默失败 - 值必须是字符串
'paused'或'running',不能是布尔值或空字符串 - 读取当前状态请用
getComputedStyle(el).animationPlayState,返回"paused"或"running",不是null或undefined
容易被忽略的兼容性和有效性验证点
你以为加了 :hover { animation-play-state: paused; } 就万事大吉?先确认三件事:
- 元素是否真有在跑动画?
console.log(getComputedStyle(el).animationName)应返回非none的名字,且animationDuration不为0s - 是否用了 Web Animations API(如
el.animate())?那种动画完全不受animation-play-state影响,得调用animation.pause() - 是否在媒体查询里误用?比如
@media (prefers-reduced-motion) { .hero { animation-play-state: paused; } }—— 如果动画本身靠:hover启动,那媒体查询里的paused根本不会触发,因为动画压根没开始
真正起作用的永远是「动画正在运行中」这个前提。没跑起来的动画,暂停指令就是一纸空文。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











