必须用 transform: translatex() 实现侧边栏动画,因其走 gpu 合成层、不触发重排,可稳定 60fps;而 left 或 margin-left 会强制重排,导致卡顿、闪屏、错位等问题。

必须用 transform: translateX(),其他方式在真机上基本不可靠——不是卡顿掉帧,就是 iOS 闪一下才收起,或者连点错位。
为什么不能用 left 或 margin-left
这两个属性改的是布局盒模型,每次动画都要重排(reflow),低端安卓机常掉到 30fps 以下;iOS Safari 会弹黄色警告“强制降级”,DevTools 的 Performance 面板里能看到密集的 layout 标记。而 transform: translateX() 走 GPU 合成层,只重绘不重排,是唯一能稳住 60fps 的方案。
-
left: -100%在 iOS 上收起时偶尔闪一下才消失 - 点击后抽屉“顿半拍”才动,或快速连点两次导致位移错乱
- 千万别同时写
left和transform:Safari 可能直接忽略translateX()
transform: translateX(-100%) 失效的真正原因
表面没滑走,实际是位移基准算错了:-100% 按父容器宽度算,不是按侧边栏自身宽。必须同时满足三个条件:
- 侧边栏容器必须设明确
width(如width: 280px或width: min(280px, 80vw)),不能靠内容撑开 - 必须用
position: fixed或position: absolute脱离文档流,否则transform会影响主内容区导致跳动 - 初始隐藏必须写死在基础样式里:
transform: translateX(-100%),不能靠 class 切换才加——否则 transition 会失效
移动端必须动态加 will-change: transform
只在打开/关闭前瞬间通过 JS 设置:element.style.willChange = 'transform',动画结束立刻设回 'auto'。长期开着会吃内存,尤其在低端安卓机上容易卡顿。
- 缺它的话,iOS Safari 抽屉拉出一半常出现白边或闪烁(截至 2026 年 9 月)
- 必须搭配
backface-visibility: hidden,这是 iOS 必加项 -
position: fixed+will-change: transform+backface-visibility: hidden三件套缺一不可
遮罩层和滚动锁定的实操坑点
很多“点不关”“关了还能滑”的问题都出在这儿。
- 遮罩层
.overlay必须用width: 100vw; height: 100vh,别用100%——某些安卓浏览器会按父容器高度算,下半截点不到 - 层级顺序要严格:
z-index主内容为 1,遮罩为 10,侧边栏为 11;否则 iOS 上touchstart可能穿透到下层 - 滚动锁定不能只加
overflow: hidden在body上——iOS 会把滚动位置重置到顶部。得记录当前scrollTop,然后设body.drawer-open { position: fixed; top: -scrollTop; width: 100%; },关闭时用setTimeout(() => window.scrollTo(0, scrollTop), 0)延迟恢复
最易被忽略的其实是 transition 的写法:不能只写 transition: transform 0.3s 在通用选择器里,得拆到具体状态 class 上,比如 .drawer-open 控制位移、.overlay-active 控制透明度,且 visibility 必须显式声明时长,否则切换瞬间消失会引发点击穿透。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











