macOS Safari缩放页面时CSS transform动画位移异常如何修复?
问题复现说明
你遇到的是Safari 15+的已知渲染bug:@keyframes中定义的固定transform位移px值会在页面首次渲染时被缓存,页面缩放后不会重新计算适配新的像素比,因此出现位移比例偏移的问题,Chrome和Firefox没有这类缓存逻辑所以表现正常。
修复方案
方案1:改用相对父容器的定位动画(无JS,低复杂度)
由于transform: translateY()的百分比取值基于元素自身尺寸不符合需求,改为基于父容器的相对定位做动画,Safari会自动适配缩放后的实际尺寸:
<html> <head> <title></title> <style> .container { width: 100px; height: 100px; border: 1px solid red; } @keyframes frames { /* 改用top属性做位移 */ to { top: 90px; } } .element { width: 8px; height: 8px; border: 1px solid blue; animation: frames 0.8s linear infinite; /* 新增相对定位配置 */ position: relative; top: 0; } </style> </head> <body> <div class="container"> <div class="element"></div> </div> </body> </html>
该方案适合简单动画场景,缺点是top属于布局属性,动画会触发页面重绘,小元素场景下性能影响可以忽略。
方案2:CSS变量+动态监听(保留transform GPU加速)
如果需要保留transform的高性能特性,可通过监听设备像素比变化动态修正动画位移值:
<html> <head> <title></title> <style> :root { /* 定义位移变量 */ --move-offset: 90px; } .container { width: 100px; height: 100px; border: 1px solid red; } @keyframes frames { to { transform: translateY(var(--move-offset)); } } .element { width: 8px; height: 8px; border: 1px solid blue; animation: frames 0.8s linear infinite; } </style> </head> <body> <div class="container"> <div class="element"></div> </div> <script> const baseOffset = 90; const defaultDpr = window.devicePixelRatio; // 修正位移值 function adjustOffset() { const currentDpr = window.devicePixelRatio; const finalOffset = baseOffset * (defaultDpr / currentDpr); document.documentElement.style.setProperty('--move-offset', `${finalOffset}px`); } // 监听页面缩放触发的resize事件 window.addEventListener('resize', adjustOffset); </script> </body> </html>
该方案适合复杂动画场景,利用GPU加速的同时兼容Safari缩放逻辑,仅增加极小的JS运算开销。
内容的提问来源于stack exchange,提问作者mistercake
相关产品推荐
相关产品推荐

