Safari中修改元素宽度与transform:translate时过渡动画失效求助
Safari下CSS同时过渡尺寸与translate百分比的解决方案
问题原因
Safari在CSS过渡过程中,不会实时更新transform: translate(%)的计算基准(也就是元素当前的宽高)。当你同时过渡元素宽高和基于自身尺寸的translate百分比时,浏览器会直接用初始或最终的宽高来计算translate值,导致动画异常甚至失效。
解决方案
方案1:用CSS变量绑定尺寸与位移
通过CSS变量将元素宽高和translate的数值绑定,让位移计算基于变量而非实时尺寸的百分比,Safari就能正确平滑过渡:
:root { --square-size: 10rem; } .square { background-color: red; transition: all 1s; cursor: pointer; position: absolute; width: var(--square-size); height: var(--square-size); transform: translate(0, 0); } .square-expanded { --square-size: 20rem; transform: translate(calc(var(--square-size) * 0.5), calc(var(--square-size) * 0.5)); }
方案2:分离位置与尺寸到不同元素
把位置过渡和尺寸过渡拆分到两个元素上,外层管位移,内层管大小,避免相互干扰:
HTML
<div class="square-wrapper" id="square-wrapper"> <span class="square" id="square"></span> </div>
CSS
.square-wrapper { position: absolute; transition: transform 1s; transform: translate(0, 0); } .square { background-color: red; transition: all 1s; cursor: pointer; width: 10rem; height: 10rem; } .square-expanded .square-wrapper { transform: translate(10rem, 10rem); } .square-expanded .square { width: 20rem; height: 20rem; }
JavaScript
var wrapper = document.getElementById("square-wrapper"); wrapper.addEventListener("click", moveSquare); function moveSquare() { wrapper.classList.toggle('square-expanded'); }
方案3:用scale替代宽高过渡
放弃直接修改宽高,改用scale()实现尺寸变化,位移用固定值(基于原始尺寸的50%),避开百分比计算的bug:
.square { background-color: red; transition: all 1s; cursor: pointer; position: absolute; width: 10rem; height: 10rem; transform: translate(0, 0) scale(1); transform-origin: top left; /* 保证缩放从左上角开始,和原效果一致 */ } .square-expanded { transform: translate(5rem, 5rem) scale(2); }
内容的提问来源于stack exchange,提问作者raul8437
相关产品推荐
相关产品推荐

