:hover 时 animation 不触发的主因是动画默认不重播,需用 animation-play-state: running 配合 paused 初始态实现悬停重启;或改用 transition 处理简单状态变化。

hover 时 animation 不触发的常见原因
直接写 :hover { animation: fade-in 0.3s; } 很可能没反应——这不是浏览器 bug,而是 CSS 动画触发机制决定的:animation 默认只在元素首次匹配规则时启动(比如页面加载),后续通过伪类切换不会“重新播放”,除非显式重置动画状态。
animation-name 必须配合 animation-duration 和 animation-fill-mode
仅声明 animation: name 不生效;必须至少包含持续时间。更关键的是,若目标元素已有初始样式(比如 opacity: 0),而 hover 后想从 0 变到 1,需确保动画能“从头开始”:
-
animation-fill-mode: forwards只保留结束态,不解决重播问题 - 真正起作用的是让动画在 hover 瞬间“重启”,靠的是
animation-play-state或强制重绘 - 最稳妥做法:hover 时设置一个带
animation-duration的完整声明,并用animation-delay: 0s避免继承父级延迟
可靠触发方式:用 animation + animation-play-state 组合
核心思路是把动画设为暂停态,hover 时播放一次。这样每次悬停都强制重播:
button {
animation: slide-up 0.4s paused;
}
button:hover {
animation-play-state: running;
}
注意点:
立即学习“前端免费学习笔记(深入)”;
- 动画定义里不能有
animation-iteration-count: infinite,否则 hover 后会持续循环 - 若需“进+出”双向效果,得另写一个反向动画(如
slide-down)并在:not(:hover)中触发,纯 CSS 无法自动倒播 - 某些旧版 Safari 对
paused/running支持不稳定,可降级为 JS 控制classList.toggle()
替代方案:用 transition 更简单且兼容性更好
如果只是单次状态变化(如颜色、透明度、位移),transition 比 animation 更合适:
a {
opacity: 0.7;
transition: opacity 0.2s ease, transform 0.2s ease;
}
a:hover {
opacity: 1;
transform: translateY(-2px);
}
优势:
- 天然支持正向/反向过渡(移出时自动还原)
- 无需定义
@keyframes,代码量少 - 性能更好(尤其涉及
transform和opacity时) - IE10+ 全面支持,无 Safari 兼容陷阱
只有当需要多阶变化(比如先缩放再旋转再变色)、或精确控制中间帧时,才值得上 @keyframes + animation。










