You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Safari浏览器中汉堡菜单过渡动画圆形元素错位问题排查

解决Safari中汉堡菜单过渡时圆形元素错位的问题

我碰到过Safari里类似的过渡错位问题,大概率是因为你同时在过渡布局属性(top/left/width/height)和transform变换属性,Safari的渲染引擎在处理这类混合过渡时容易出现计算偏差——过渡过程中元素位置飘了,但结束后又能回到正确位置。

咱们来调整代码,尽量用transform来处理所有位置和尺寸的变化(或者至少把布局属性和变换属性的过渡逻辑分开),避免触发不必要的重排,让Safari能正确计算过渡动画:

修改后的完整代码

CSS部分

.navicon {
 width: 20px;
 height: 15px;
 position: absolute;
 top: 30px;
 left: 50%;
 display: inline-block;
 transition: all 300ms ease;
 cursor: pointer;
 z-index: 101;
 /* 初始居中用transform统一控制,避免后续修改left/top */
 transform: translateX(-50%);
}
.navicon .line {
 position: absolute;
 width: 100%;
 height: 3px;
 background-color: #000;
 transition: all 300ms ease;
 /* 移除left:50%,子元素位置全靠transform控制 */
 left: 0;
}
.navicon .ham {
 top: 40%;
 background-color: transparent;
 box-shadow: 0 0 0px 3px #000 inset;
 box-sizing: border-box;
 transform: translateX(-50%);
}
.navicon .bun--top {
 top: 0;
 transform: translateX(-50%);
}
.navicon .bun--bottom {
 top: 80%;
 transform: translateX(-50%);
}
.navicon.clicked {
 /* 移除top/right,改用transform实现位置偏移+旋转,避免混合布局属性 */
 transform: translate(calc(100vw - 40px), -7px) rotate(180deg);
 width: 30px;
 height: 30px;
}
.navicon.clicked .ham {
 top: 0;
 left: 0;
 height: 100%;
 width: 100%;
 border-radius: 50%;
 /* 只用transform控制居中+旋转,不再修改top/left */
 transform: translate(-50%, -50%) rotate(135deg);
 box-shadow: 0 0 0px 2px #000 inset;
}
.navicon.clicked .bun {
 top: 50%;
 width: 10px;
}
.navicon.clicked .bun--top {
 transform: translate(-50%, -50%) translateX(-4px);
 height: 3px;
}
.navicon.clicked .bun--bottom {
 background-color: transparent;
 transform: translate(-50%, -50%) translate(-8px, -1px);
 width: 0;
 height: 0;
 border-top: 4px solid transparent;
 border-right: 4px solid #000;
 border-bottom: 4px solid transparent;
}

JavaScript和HTML部分(无需修改)

let navicon = document.querySelector('#navicon');
navicon.addEventListener('click', toggleMenu, false);
function toggleMenu(event) {
 navicon.classList.contains('clicked') ? navicon.classList.remove('clicked') : navicon.classList.add('clicked');
}
<div id="navicon" class="navicon">
 <div class="line bun bun--top"></div>
 <div class="line ham"></div>
 <div class="line bun bun--bottom"></div>
</div>

关键修改说明

  • 把.navicon和所有子元素的初始定位统一用transform: translateX(-50%)实现居中,不再依赖left:50%,避免过渡时混合布局属性和变换属性。
  • .navicon.clicked不再修改top和right,而是用transform: translate(...)来实现位置偏移,结合旋转,让过渡逻辑更连贯。
  • 微调了.bun--bottom的transform值,确保箭头的位置在Safari过渡过程中不会出现偏移。

这样修改后,所有过渡都围绕transform和尺寸属性展开,减少了Safari需要计算的布局变化,应该就能解决过渡过程中的错位问题了,你可以在Safari里测试下这个版本~

内容的提问来源于stack exchange,提问作者Arsengael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:44:41