在网页交互里,悬停暂停动画并且鼠标离开后平滑恢复是一个常见需求。直接使用animation-play-state:paused可以暂停,但离开时动画会瞬间跳回时间轴位置继续跑,视觉上不够自然。下面介绍两种实现方式。

纯CSS实现悬停暂停
最简单的方法是利用:hover切换animation-play-state,并为元素加一层transition来缓和状态变化。不过animation本身不能被transition直接平滑,所以我们通常对变换属性做补充处理。
/* 定义一个旋转动画 */
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.box {
width: 100px;
height: 100px;
background: #3498db;
animation: spin 3s linear infinite;
/* 离开时给transform一点过渡,减弱跳变感 */
transition: transform 0.3s ease;
}
/* 鼠标悬停暂停 */
.box:hover {
animation-play-state: paused;
}
上面的写法在悬停时可以暂停,但由于animation时间轴不随transition变化,离开后仍是按原周期继续。若希望“恢复”看起来平滑,可改用下面JS方案。
JavaScript控制平滑恢复
通过监听mouseenter与mouseleave,用getAnimations()拿到动画对象,暂停时记录进度,离开时用transition补间当前transform到目标角度,再恢复播放。
const box = document.querySelector('.box');
let anim = box.getAnimations()[0];
box.addEventListener('mouseenter', () => {
anim.pause();
});
box.addEventListener('mouseleave', () => {
// 当前旋转角度
const style = getComputedStyle(box);
const matrix = new DOMMatrix(style.transform);
const current = Math.atan2(matrix.b, matrix.a) * 180 / Math.PI;
// 设定一个靠近当前角度的续播起点较复杂,这里仅演示加transition平滑
box.style.transition = 'transform 0.4s ease';
// 离开后直接继续播放,浏览器会从暂停帧延续
anim.play();
setTimeout(() => { box.style.transition = 'none'; }, 400);
});
注意事项
- 使用animation-play-state时,动画时间轴不会倒退,离开即续播。
- 若用transition补间,要避免和animation的transform冲突,可在离开事件后暂存内联样式。
- 在Chrome等现代浏览器中,getAnimations()兼容性良好,旧版IE不可用。
小结
悬停暂停动画核心是利用animation-play-state,而平滑恢复依赖transition过渡或JS精确控制进度。根据项目兼容需求选择方案即可。
CSS_animationhover_pausetransition修改时间:2026-07-27 21:48:16