:hover 时 animation 不触发的主因是动画默认不重播,需用 animation-play-state: running 配合 paused 初始态实现悬停重启;或改用 transition 处理简单状态变化。
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 只保留结束态,不解决重播问题animation-play-state 或强制重绘
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 无法自动倒播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 时)只有当需要多阶变化(比如先缩放再旋转再变色)、或精确控制中间帧时,才值得上 @keyframes + animation。