animation-fill-mode: forwards 是动画“真正落地”的必要开关,否则动画结束即回退;常见失效原因包括动画未执行、样式被覆盖、与transition冲突、js动态设置时遗漏或简写属性重置,默认none会覆盖已设的forwards。

animation-fill-mode: forwards 不是锦上添花的修饰,而是决定动画是否“真正落地”的开关。没它,@keyframes 里写的 100% 样式几乎白写——动画一停,元素立刻弹回初始位置或透明度。
为什么写了 forwards 却没留住状态
常见现象:元素执行完 translateX(200px) 动画后瞬间跳回原点;hover 触发的淡入动画,鼠标移开就消失;JS 添加类名后读取 getComputedStyle(el).transform 拿到的是旧值。
- 动画根本没执行完:
animation-duration: 0s、animation-iteration-count: 0或被animation-play-state: paused卡住,forwards就不生效 - 样式被覆盖:动画设了
opacity: 0,但后续有.box { opacity: 1 }这类通用规则,层叠优先级更高,直接干掉forwards的效果 - 和
transition冲突:同一属性(如transform)同时被transition和animation控制,动画结束瞬间可能触发意外过渡,看起来像“没冻住” - JS 动态设置时漏掉它:用
el.style.animation = 'slide 0.3s ease'会把整个animation属性重写,animation-fill-mode被重置为默认none,必须显式补上:el.style.animation = 'slide 0.3s ease forwards'
animation 简写会悄悄覆盖 forwards
很多人只写 animation: slide 0.3s ease;,以为 forwards 已在 CSS 类里定义好了——错。CSS 简写属性会把未显式声明的子属性重置为默认值。
-
animation简写包含 8 个子属性,其中animation-fill-mode默认就是none - 哪怕你在类里写了
animation-fill-mode: forwards,只要后面出现任何animation: ...简写,它就被覆盖掉 - 正确写法只有两种:
animation: slide 0.3s ease forwards;(全写在简写里),或分开写:animation-name: slide; animation-duration: 0.3s; animation-timing-function: ease; animation-fill-mode: forwards;
连续动画衔接时 forwards 必须成对出现
想让元素先滑入、再缩放、最后变色,三段动画无缝衔接?90% 的断裂问题出在 fill-mode 和关键帧首尾不一致。
- 第二段动画的
0%必须和第一段的100%完全一致:包括单位(translateX(100px)≠translateX(100))、函数写法(scale(1.2)≠transform: scale(1.2)) - 每一段都得带
forwards,否则中间一停就回退 -
animation-delay要累加:第二段delay= 第一段duration,第三段delay= 前两段duration之和 - 避免用
infinite:如果某段设了animation-iteration-count: infinite,forwards实际无效(因为没有“结束”)
编辑器中调试 animation-fill-mode 的实际建议
在 VS Code、WebStorm 或浏览器 DevTools 里调这个属性,重点不是“有没有写”,而是“有没有生效”。
- 在 Elements 面板里选中元素,看 Computed 标签页下的
animation-fill-mode值是否为forwards,且没被!important或更高优先级规则覆盖 - 临时禁用其他影响同一属性的规则(比如全局
transition、父级transform),排除干扰 - 用
requestAnimationFrame延迟读取最终样式:requestAnimationFrame(() => console.log(getComputedStyle(el).transform)),避免因渲染时机导致误判 - Safari ≤14.1 对
transform多函数组合(如scale(1.1) rotate(5deg))偶有forwards渲染残留,可加一句transform: translateZ(0)强制硬件加速兜底
最常被忽略的一点:当你在编辑器里改完 CSS、保存、刷新页面,看到动画还是闪回——别急着改 @keyframes,先检查 DevTools 里 animation-fill-mode 是否真的被应用了,以及有没有被 JS 或简写规则悄悄覆盖掉。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











