必须用transform: translateX(),因其走GPU合成层、不触发重排,而left/margin-left强制同步布局导致卡顿掉帧;需配合position: fixed/absolute、明确width、will-change动态启用硬件加速及遮罩层滚动锁定。

必须用 transform: translateX(),其他方式在真机上基本不可用——不是卡顿就是闪动,iOS Safari 还会弹黄色警告说“强制降级”。
为什么不能用 left 或 margin-left
这两个属性改的是盒模型位置,浏览器必须反复计算布局(reflow),动画一跑就掉帧。低端安卓机常卡在 30fps 以下;iOS Safari 甚至会直接忽略部分帧,导致抽屉“跳一下”才展开或收起。
-
left: -100%在 iOS 上偶尔闪一下才隐藏,是因为浏览器在重排和合成之间摇摆 - 别同时写
left和transform:行为难预测,Safari 可能直接忽略translateX(-100%) -
translateX(-100%)是相对自身宽度的位移,比-300px更适配不同设备;但如果侧边栏宽度固定(如width: 280px),用translateX(-280px)更精准
transform 动画必须搭配的定位与显隐控制
侧边栏容器没设对定位,translateX() 就会错位或挤占主内容区。也不能用 display: none 或 visibility: hidden 做初始隐藏——这会让 transition 失效。
- 必须设
position: fixed(全屏抽屉)或position: absolute(局部抽屉),并撑满视口:top: 0; left: 0; width: 100%; height: 100dvh; - 初始状态写死:
transform: translateX(-100%);,不要靠 class 控制隐藏 - 收起后若需彻底禁用交互,用
visibility: hidden; opacity: 0; pointer-events: none;组合,而不是display: none - 动态加
will-change: transform(仅在打开/关闭瞬间 set),避免常驻开销
遮罩层、滚动锁定与事件穿透的实操细节
遮罩层不是摆设,它直接决定点击是否可靠、背景是否乱滚。“点不关”“关了还能滑”的问题基本都出在这儿。
立即学习“前端免费学习笔记(深入)”;
- 遮罩层
.overlay必须position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;(别用100%,某些安卓浏览器算的是父容器高度) - 层级顺序要严格:
z-index主内容区为 1,遮罩层为 10,侧边栏为 11;否则 iOS 上touchstart可能穿透到下层 - 滚动锁定必须加在
body上:.no-scroll { overflow: hidden; height: 100vh; overscroll-behavior: contain; },JS 打开时加,关闭时立刻移除(别等transition结束) - 监听遮罩层关闭,用
click而非touchend:后者在快速点击时容易漏触发;但要注意pointer-events: auto必须显式设置
真正麻烦的不是写几行 transform,而是 will-change 加得不对、z-index 层级错一位、或者 overflow: hidden 加在了错误的元素上——这些地方一错,真机一测就露馅。


















