animation-fill-mode: forwards 在旧浏览器中常被静默忽略,需在 animation 简写中显式声明、100% 关键帧写全 transform、避免动态覆盖,并注意终态受后续布局影响。

animation-fill-mode: forwards 在旧浏览器中“看起来没生效”,不是你写错了,而是它压根没被正确解析或应用——尤其在 Android 4.4 WebView、iOS Safari ≤14.1 这类内核中,forwards 常被静默忽略或部分失效。
旧内核把 forwards 当提示,不是指令
Android 4.4(Blink 40–44)和 iOS Safari ≤14.1 将 animation-fill-mode 视为可选渲染提示,而非强制行为。即使你在 CSS 里单独写了 animation-fill-mode: forwards;,只要 animation 简写没显式包含它,内核就可能跳过。
- ❌ 错误写法:
animation: slideIn 0.3s ease;+ 单独一行animation-fill-mode: forwards; - ✅ 正确写法:
animation: slideIn 0.3s ease forwards;(注意分号前有空格) - 部分 WebView 对
to关键帧解析不稳定,必须改用100%——例如写@keyframes slideIn { 0% { ... } 100% { transform: translateX(100px); } },别用to
transform 终态丢失:不是回弹,是没存全
旧 Safari(≤14.1)在复合 transform 场景下,forwards 只能捕获你在 100% 中**显式写出的属性值**,其余自动归 none。比如元素原始有 transform: scale(0.95) rotate(2deg),动画只写 100% { transform: translateX(100px); },结束时 scale 和 rotate 就消失了。
- 必须在
100%中一次性写全:transform: translateX(100px) scale(0.95) rotate(2deg); - 若原始
transform来自 JS 或动态 class,无法预知全部值,建议放弃transform动画,改用left/top+position: relative - 加
will-change: transform;可提升旧 Safari 对终态缓存的可靠性,但仅限动画元素,别滥用
JS 动态设置动画时,animationFillMode 容易被覆盖
在 Cordova、Capacitor 或微信小程序 WebView 中,用 JS 设置 element.style.animation 后,CSS 文件里写的 animation-fill-mode 会被内联样式覆盖或忽略。
- 必须同步设置:
element.style.animation = 'slideIn 0.3s ease forwards';或分开写:element.style.animation = 'slideIn 0.3s ease'; element.style.animationFillMode = 'forwards'; - 如果用 class 控制动画,确保 class 添加后动画真实执行完毕——快速 toggle、
animation-play-state: paused或animation-iteration-count: infinite都会让forwards失效 -
animationend事件里读取getComputedStyle,可能拿到中间值;真要取终态,建议在事件回调里再setTimeout(..., 0)一次
最常被忽略的一点:forwards 锁住的是动画**结束那一刻的计算值**。之后父容器重排、视口缩放、媒体查询切换,都会让“定格”的样式重新参与计算——这时候问题已不在 animation-fill-mode,而在响应式上下文本身。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











