animation-fill-mode: forwards 必须显式声明,否则动画结束会立即回退到初始状态;它仅保留最后一帧样式,不改变文档流或交互,需配合js设置display:none等才能彻底隐藏。

animation-fill-mode: forwards 是必须显式写的
不加这句,动画播完就“啪”一下弹回初始状态,不是你关键帧写错了,是浏览器默认 animation-fill-mode: none 在起作用。哪怕 @keyframes 里 100% 写了 transform: scale(0.8),播完也不会保留——它只在播放期间生效。
实操建议:
- 只要需要停在最后一帧,就必须加
animation-fill-mode: forwards - 不能靠 JS 移除动画 class 来“重置”,那会连带清掉
forwards保留的样式 - 多个动画同时作用于同一元素时,每个都要单独设
animation-fill-mode,不会继承或自动同步
为什么只设 forwards 还是没留住?检查这些地方
常见现象:加了 forwards,但元素还是回退了。大概率是下面几个地方被覆盖或干扰:
-
transition和animation同时作用于同一个属性(比如都动opacity),transition的终态计算可能覆盖animation的forwards结果 - 动画结束后又通过 JS 清空了
style或切换了 class,导致内联样式/类样式把forwards的计算值冲掉了 - 用了
animation-direction: alternate却没注意:forwards停的是最后一次正向播放的末帧,不是所有循环里的最大位移 - 关键帧里用的是
to而不是100%,某些旧版渲染引擎对to解析不稳定(虽少见,但真有)
想彻底隐藏动画结束后的元素?仅靠 forwards 不够
animation-fill-mode: forwards 只能保留最后一帧的 CSS 属性值,比如 opacity: 0 或 transform: translateX(200px),但它不会让元素真正脱离文档流或禁用交互。
如果目标是“动画淡出后完全不可见、不可点、不占空间”,得配合 JS:
- 监听
animationend事件 - 在回调里设
element.style.display = 'none'和element.style.pointer-events = 'none' - 注意:别在事件里直接删 class,否则可能触发重绘异常;优先用
style固化
单纯依赖 opacity: 0 + forwards,元素仍响应点击、仍参与布局(除非还加了 visibility: hidden)。
backwards 和 both 容易误用的点
加 animation-delay 时,很多人顺手加 backwards,结果发现元素提前“闪现”或位置错乱。
原因很直接:
-
backwards只在animation-delay阶段生效,应用的是0%或from的样式;没有delay,它等于none -
both不是“全程保持”,而是分段控制:延迟期用首帧,播放完用末帧;中间过程照常执行 - 如果动画本身没定义
0%,浏览器会取当前 computed style 当作起始态,可能导致意外偏移
最稳妥的做法:需要延迟前就定位,就明确定义 0%;需要播完就消失,就明确定义 100% + forwards;别指望浏览器猜你要什么。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











