ios webkit对animation-duration

animation-duration 小于 150ms 时 iOS WebKit 直接跳过首帧
很多开发者设了 animation-duration: 0.1s 或 0.05s,结果在 iPhone Safari 或微信 WebView 里完全看不到动画——不是卡顿,是压根不触发。WebKit 对极短动画做了硬性过滤:低于 150ms(即 0.15s)的动画会被直接忽略首帧,连计时器都不启动。
实操建议:
- 把所有移动端关键动画的
animation-duration显式设为 ≥0.15s,例如0.2s或0.25s - 别依赖浏览器默认值(默认是
0s),必须写全简写或单独声明 - 如果真需要“瞬时”反馈,改用
transform+transition配合will-change,它不受此限制
元素初始为 display: none 或未插入 DOM 时 animation-delay 不生效
animation-delay 不是“倒计时闹钟”,它只在元素已挂载、处于渲染树中且样式已计算完毕时才开始计时。移动端常见场景:Vue/React 组件懒加载后动态插入、display: none 切换、或用 visibility: hidden 预占位但未触发 layout。
实操建议:
- 避免对
display: none元素设置动画类——它会彻底跳过整个动画生命周期 - 改用
opacity: 0; pointer-events: none;+transform: scale(0.98)等不可见但仍在渲染树中的方式隐藏 - 动态插入元素后,用
requestAnimationFrame(() => el.classList.add('animate'))确保样式已就绪再启播
内联 transform 样式劫持动画起点,导致跳帧或不触发
哪怕只执行过一次 el.style.transform = 'scale(0.95)',后续 CSS 动画里的 @keyframes 中定义的 transform 就会和这个内联值冲突。iOS Safari 尤其敏感:它可能直接放弃插值,表现为动画瞬间完成、卡在中间态,或干脆不播。
实操建议:
- 每次重播前清空内联
transform:el.style.transform = '' - 不要混用 JS
transform和 CSS 动画控制同一属性;要么全 JS(用requestAnimationFrame),要么全 CSS(靠 class 切换) - 若需 JS 控制过渡起点,改用 CSS 自定义属性驱动:
el.style.setProperty('--scale', '0.95'),再在@keyframes中用transform: scale(var(--scale))
visibilitychange 事件在 iOS 上延迟或错报,导致重播逻辑失效
iOS Safari 和微信 WebView 中,document.visibilityState 常被错报为 'visible'(即使页面已切后台),且 visibilitychange 事件响应延迟可达 500ms。单靠它做动画重播,大概率失败。
实操建议:
- 必须同时监听
visibilitychange、pageshow、focus三个事件 - 重播动作包一层
setTimeout(() => { /* 移类 → offsetHeight → 加类 */ }, 100),绕过初始状态同步窗口 - 关键三步缺一不可:
el.classList.remove('animate')→void el.offsetHeight(强制 reflow)→el.classList.add('animate'),且动画类中必须含animation-fill-mode: none
移动端动画不自动播,往往不是“没写对”,而是被 WebKit 的节电策略、样式层叠顺序、或 DOM 生命周期细节卡住了。最常漏的是那句 el.style.transform = '' 和那个 offsetHeight ——少了它们,其他都白搭。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











