animation-fill-mode: forwards 使动画结束后保持最后一帧样式;默认 none 会回退到初始状态,forwards 需与 animation 同时使用,both 则兼具延迟前首帧和结束后末帧效果。

animation-fill-mode: forwards 为什么动画一结束就回退
默认情况下,CSS 动画播放完会“撤回”所有关键帧里设置的样式,回到动画开始前的状态。这不是 bug,而是 animation-fill-mode 的默认值是 none —— 它压根不保留任何动画期间的样式。
要让元素停在最后一帧的样子,必须显式设为 forwards:
div {
animation: slideIn 0.3s ease-out;
animation-fill-mode: forwards;
}
注意:只写 animation-fill-mode: forwards 不生效,它必须和 animation 或其子属性(如 animation-name)一起存在才起作用。
forwards 和 both 的区别在哪
forwards 只保留动画最后一帧的样式;both 是 forwards + backwards 的组合,即:动画开始前应用第一帧(@keyframes 中 0% 或 from),结束后保持最后一帧。
常见误用场景:
- 用了
animation-delay,但没加backwards→ 元素在延迟期间仍显示初始状态,不是第一帧状态 - 想让动画从隐藏态开始、结束时保持可见,却只设
forwards→ 延迟阶段还是可见的,得配both
示例:
@keyframes fade {
from { opacity: 0; }
to { opacity: 1; }
}
div {
animation: fade 1s 0.5s both; /* 0.5s 延迟,延迟时就已是 opacity: 0 */
}
animation-fill-mode 对 transform 动画特别容易踩坑
当动画里用了 transform(比如 translateX(100px)),如果没设 forwards,动画一结束,transform 就被清空,元素瞬间“弹回”原位 —— 看起来像闪一下。
更隐蔽的问题:
- 父容器有
overflow: hidden,动画中元素移出可视区,但结束回退导致又露出来 - 后续 JS 操作依赖元素最终位置(比如
getBoundingClientRect()),没加forwards就拿到的是原始位置 - 和其他 transition 同时存在时,
forwards设置的 transform 会覆盖 transition 的起始值,造成冲突
兼容性和替代方案要不要考虑
animation-fill-mode 在 IE10+、Edge 12+、Chrome 43+、Firefox 16+ 都支持,移动端 iOS Safari 9.0+ 也没问题。真要兼容老版本 IE,只能放弃 CSS 动画,改用 JS 控制 class 切换 + 手动设内联样式。
但要注意:forwards 仅影响渲染样式,不会修改 DOM 的 style 属性。也就是说,JS 读 element.style.transform 还是空字符串,得用 getComputedStyle(element).transform 才能拿到动画结束后的实际值。
复杂交互动画里,forwards 看似简单,但一旦混用 JS 控制、多段动画衔接、或响应式重触发,就很容易漏掉这个设置,或者误以为它能“永久固化”样式 —— 它只是渲染层的快照,不是状态持久化。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











