动画结束后样式“闪回”是因animation-fill-mode默认为none,应设forwards保持结束帧;若无效需检查是否无限循环、关键帧漏属性或被高优先级样式覆盖。

动画结束后元素样式“闪回”到初始状态
这是最常见的表现:比如一个按钮用 @keyframes 做了淡入 + 上移,播放完立刻跳回透明度 0、位移 0 的原始位置。根本原因不是动画写错了,而是 CSS 动画默认不保留结束帧的样式。
-
animation-fill-mode默认值是none,意味着动画只在运行期间生效,结束后立即撤销所有动画内声明的样式 - 只要动画有明确的终点(比如
to或100%定义了opacity: 1; transform: translateY(-10px);),就该用animation-fill-mode: forwards; - 注意:它只影响「动画结束后的保持」,不影响动画开始前——如果还想让元素一开始就呈现第一帧样式,得加
both
animation-fill-mode: forwards 不生效?检查这些地方
写了 forwards 却还是闪回,大概率卡在以下三处:
- 动画没真正“结束”:比如设置了
animation-iteration-count: infinite,或者用animation-play-state: paused暂停在中间,forwards就不会触发 - 关键帧里漏写了某个属性:例如动画中只改了
transform,但没提opacity,那即使写了forwards,opacity也不会保持——CSS 不会自动继承未声明的属性值 - 被更高优先级样式覆盖:比如动画结束后,外部类名又设了
opacity: 0,那forwards保持的opacity: 1就会被覆盖。用浏览器开发者工具看 computed 样式,确认最终生效的是哪条规则
和 transition 结束状态的区别
别把 animation-fill-mode 和 transition 混用。transition 是响应属性变化的即时过渡,它本身不定义“结束状态”,结束状态就是你 JS 或 class 切换后设置的那个值;而 animation 是预定义好一整段过程的,必须靠 fill-mode 显式说清楚“停在哪儿”。
- 想让 hover 后元素保持高亮?用
transition配合 class 切换更直接,不用碰fill-mode - 想让元素入场后固定在某个位置,且入场逻辑较复杂(比如多段位移+缩放+旋转)?那就得用
@keyframes+animation-fill-mode: forwards - 两者混用时特别容易冲突:比如动画里设了
transform: scale(1.2)并forwards,但紧接着 JS 又给元素加了个scale(0.8)的 inline style,那后者会赢
兼容性与性能提醒
animation-fill-mode 在所有现代浏览器里都稳,IE10+ 也支持,基本不用垫片。但它有个隐含成本:一旦启用 forwards,浏览器就必须在动画结束后持续维护那个“保持态”的渲染层,尤其在大量元素同时动画时,可能增加内存占用。
立即学习“前端免费学习笔记(深入)”;
- 移动端低端机上,如果动画元素很多(比如列表项逐个飞入),建议动画结束后用 JS 清掉
animation相关声明,转为用 class 固定终态样式 -
forwards不会触发布局重排(reflow),但会维持合成层(compositor layer)。如果动画只涉及transform和opacity,问题不大;若动了width、height或left/top,长期保持可能引发意料外的渲染开销
forwards 就万事大吉,结果关键帧里漏属性、或被后续样式覆盖——得真去 devtools 里点开 computed,盯着那一行 opacity、transform 看它到底有没有生效。


















