animation-fill-mode: forwards 是解决动画结束后样式回退的唯一可靠方案,必须写在触发动画的css规则中;ios safari对forwards支持严格,需避免display变更、确保keyframes已定义,并注意其仅作用于动画层而非布局层。

动画结束后样式自动回退到初始值,不是 bug,是 animation 的默认行为 —— 除非你明确告诉它“停在最后一帧”。
为什么 animation-fill-mode: forwards 必须加
移动端(尤其是 iOS Safari)对动画结束态的处理非常严格:不加 fill-mode,动画一停,元素立刻恢复 animation 开始前的样式(哪怕你用 transform 或 opacity 改了值)。这不是渲染延迟,是规范定义的行为。
实操建议:
-
forwards是唯一能“锁住”动画最后一帧样式的取值;both虽然也包含forwards,但会同时应用backwards(可能覆盖初始样式),多数场景只需forwards - 必须写在触发动画的 CSS 规则里,不能只靠 JS 添加 class 后再补 —— 动画已开始,补无效
- 注意:如果动画本身用的是
keyframes中的0%和100%定义,forwards只保留100%的声明,其他未声明的属性不会继承
transform 动画后 getComputedStyle 仍返回原始值?
这是常见错觉:JS 读取的 transform 值永远是初始声明值(比如 none),不是动画中或结束后的计算值。浏览器不会把动画终态“写回”内联样式或 computed style。
实操建议:
- 不要依赖
getComputedStyle(el).transform判断动画是否到位 —— 它几乎总是错的 - 改用 CSS 自定义属性 +
@property(仅 Chrome/Edge 支持)或监听animationend事件打标记 - 若需 JS 后续操作(如移除元素),应在
animationend回调里执行,而不是轮询样式
iOS Safari 下 forwards 失效的典型诱因
不是所有情况加了 forwards 就稳 —— iOS 16.4+ 修复了很多问题,但仍有几个硬坑:
实操建议:
- 避免在动画中同时修改
display(如none→block):iOS 会忽略forwards,直接重置 -
animation-name必须是非空、已定义的@keyframes名;若 JS 动态插入 keyframes 但未及时生效,forwards无作用 - 使用
will-change: transform可提升渲染稳定性,但别滥用 —— 可能引发额外图层和内存开销 - 若动画由
visibility或opacity驱动,确保结束帧显式声明该属性(例如100% { opacity: 0; }),否则forwards不生效
真正麻烦的不是加不加 forwards,而是它只管动画层,不管布局层 —— 如果动画结束时元素尺寸变化影响了父容器流式布局,闪回感可能来自重排,而非样式丢失。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











