animation-fill-mode 是决定动画结束状态是否保留的关键属性,必须显式设置为 forwards 才能使 100% 关键帧样式持久生效;其默认值 none 会导致动画一结束即回退初始状态。

animation-fill-mode 不是“锦上添花”的可选项,而是决定动画是否真正生效的关键开关。没设它,@keyframes 里写的 100% 样式大概率不会留在 DOM 上——动画一停,元素立刻弹回初始状态。
为什么 animation-fill-mode: forwards 必须显式写
浏览器默认值是 none,意味着动画只在运行中起作用,结束后立即丢弃所有动画样式,回归其他 CSS 规则(比如 transform: translateX(0))的控制。即使你在 @keyframes 里写了 100% { transform: translateX(100px); },没加 animation-fill-mode: forwards,元素根本不会停在 100px 处。
-
forwards让元素保持最后一帧计算出的样式(注意:不是“渲染快照”,而是真实应用的 CSS 值) - 简写
animation属性会覆盖animation-fill-mode为none,所以别只写animation: slide 0.3s ease;,要补全:animation: slide 0.3s ease forwards; - 如果动画有
animation-iteration-count: infinite,forwards实际无效(因为没有“结束”),此时它只影响单次播放或有限循环
backwards 和 both 的真实使用场景
backwards 不是“让动画从某处开始”,而是在 animation-delay 阶段就提前应用第一帧样式;both 是两者的叠加,但容易被误用。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 想实现“hover 前先隐藏,hover 后淡入”,需配合
animation-delay: 0.5s+animation-fill-mode: backwards,否则延迟期间元素仍可见 -
both看似全能,但若0%关键帧和元素原始样式冲突(比如原始opacity: 1,0%设了opacity: 0),会导致页面加载瞬间闪一下 -
backwards只在存在animation-delay时才有意义;无 delay 时它和none行为一致
连续多段动画衔接失败的典型原因
连续动画断裂,90% 是因为没处理好 animation-fill-mode 和关键帧首尾一致性。
- 第二段动画的
0%必须和第一段的100%完全一致(包括单位、函数写法,translateX(100px)≠translateX(100)) - 每段都必须带
forwards,且animation-delay要累加:第二段 delay = 第一段 duration,第三段 delay = 前两段 duration 之和 - 避免用
transition混合控制同一属性(如同时对transform用 transition 和 animation),会导致末帧被 transition 覆盖而闪回
最容易被忽略的一点:当你用 JavaScript 动态添加动画类名时,animation-fill-mode 的效果依赖于浏览器重排(reflow)时机。如果类名添加后立刻读取 getComputedStyle(el).transform,可能拿到的是旧值——不是 bug,是 CSS 动画的异步应用机制决定的。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










