animation-fill-mode: forwards 是保持动画结束状态的必要设置,必须显式声明才能使100%关键帧样式持续生效,否则元素会跳回原始样式。

animation-fill-mode: forwards 是保持动画结束状态的必要设置
动画播完后元素“啪”一下跳回原始样式,不是动画写错了,而是 animation-fill-mode 默认值是 none——它压根不保留任何动画期间的样式。只加 animation 简写或单独写 animation-name、animation-duration 都没用,必须显式声明 animation-fill-mode: forwards 才能让最后一帧的样式持续生效。
常见错误现象包括:滑入动画结束瞬间元素归位、淡出后 opacity 又变回 1、旋转停住后角度重置为 0。这些都不是关键帧漏写了,而是缺少这个填充模式控制。
-
forwards只影响动画播放结束后(即animation-iteration-count指定的最后一次迭代完成之后)的状态,对animation-delay阶段无影响 - 它保留的是
@keyframes中100%或to声明的样式,哪怕你用了animation-iteration-count: 2,它也只保留第二次循环结束时的末帧 - 多个动画同时作用在同一个元素上时,每个动画需单独设置
animation-fill-mode,父级不会继承,也不能靠一个声明统管全部
为什么只写 forwards 还是没效果?检查这三处硬性条件
animation-fill-mode: forwards 不是“一贴就灵”的膏药,它依赖三个前提同时成立:
-
@keyframes中必须有明确的100%(或to)帧,并且该帧里要写出你想保留的所有属性值,比如transform: translateX(200px) scale(1.2);如果只写了translateX,那scale就会被重置为none - 不能被
display: none或visibility: hidden覆盖:即使opacity: 1和transform都生效了,display: none仍会让元素不可见 - 必须和
animation相关属性共存才起作用——单独写animation-fill-mode: forwards在 CSS 中无效;推荐直接用简写:animation: slideIn 0.4s ease forwards
backwards 和 both 不是锦上添花,而是特定场景刚需
如果你设置了 animation-delay: 0.5s,但希望元素在等待的 0.5 秒内就提前显示动画起始态(比如已移到左侧、已设为半透明),那就必须加 backwards。否则那段时间元素还是原始样式,动画一启动就“突然出现”,视觉割裂感很强。
立即学习“前端免费学习笔记(深入)”;
both 是 forwards + backwards 的组合,不是“更高级选项”,而是分段控制:延迟期间用首帧样式,播放结束后用末帧样式。中间动画过程不受影响。
- 典型适用场景:
button:hover缩放动画——鼠标移上瞬间就开始放大(backwards提前应用transform: scale(1.2)),松开后动画播完仍保持放大(forwards) -
backwards仅在存在animation-delay时生效;没有 delay,它等价于none - 首帧和末帧若对同一属性设了冲突值(如
transform同时含rotate和scale),both会如实应用,不会自动调和或合并
JS 动态设置 animation-fill-mode 容易忽略的时机问题
用 JS 设置 element.style.animationFillMode = 'forwards' 时,必须确保在动画开始前完成赋值。如果是在 click 回调里先改样式再触发动画,但没加 setTimeout 或 requestAnimationFrame 做微任务调度,浏览器可能把两个操作合并到同一帧,导致 forwards 未被识别。
更稳妥的做法是:用 animationend 事件兜底手动固化最终样式,尤其当动画由 JS 控制启停、或需要兼容老版本 Safari(animation-fill-mode 在 iOS
element.addEventListener('animationend', () => {
element.style.transform = 'translateX(100px)';
element.style.opacity = '1';
});
注意:这种 JS 方式无法替代 forwards 对所有动画属性的统一控制,只能作为补充;且需手动维护每条关键帧里的最终值,容易遗漏或写错。


















