不能用 width/height 控制抽屉显隐,因其触发重排、卡顿、input 失焦;应使用 transform: translateX() 配合固定宽度实现 GPU 加速位移动画。

直接用 width 或 height 过渡控制抽屉显隐是错的——它触发重排、卡顿、input 失焦、移动端基本不可用。真正该做的是用 transform: translateX() 配合固定尺寸,让盒模型“不动”,只位移。
为什么不能用 width/height 控制抽屉显隐
浏览器对 width 变化的动画不启用硬件加速,每次帧都要重新计算布局(reflow),尤其在 Safari 和低端安卓 WebView 中极易掉帧。更实际的问题是:width: 0 时 <input> 虽仍可聚焦,但光标不可见、placeholder 渲染异常;若父容器有 overflow: hidden,还可能出现“只拉出一半”的截断现象。
-
width: 0 → width: 320px是 layout 动画,性能远低于 transform - 中文字体 + emoji 混排时,内容宽度动态溢出,
width值与视觉不符 - 媒体查询临界点抖动会导致状态丢失,比如 iPad 横竖屏切换时抽屉卡在半开
必须用 transform: translateX() + 固定 width
translateX() 不改变文档流,只走合成层(GPU 加速),位移过程完全不触发重排,iOS Safari 也不会报黄色警告。但前提是侧边栏必须有明确宽度,否则 translateX(-100%) 的“100%”无从计算。
- 默认状态:
transform: translateX(-100vw)(彻底移出视口左边界) - 激活状态:
transform: translateX(0),配合transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) - 必须设
width: 320px或width: 100vw,不能依赖width: auto - 别同时写
left和transform——行为不可控,容易偏移或中断动画
CSS 变量驱动盒模型尺寸时的单位陷阱
想用 CSS 变量动态改 padding、margin 或抽屉宽度?可以,但变量值必须自带单位。CSS 不会自动补 px,--width: 200 是非法长度值,width: var(--width) 会被忽略或报错。
立即学习“前端免费学习笔记(深入)”;
- ✅ 正确:
element.style.setProperty('--width', '320px')或 HTML 中style="--width: 320px;" - ❌ 危险:
style="--width: 320"+width: var(--width) - ⚠️ 少用替代方案:
width: calc(var(--width-num) * 1px),冗余且易出错 - 对
padding/margin,推荐显式用逻辑属性:padding-block: var(--pb),避免简写继承问题
移动端真机上最常被忽略的三件事
抽屉在开发环境看着顺滑,一上真机就卡、点不中、关不掉——往往不是动画逻辑错了,而是这几个点没对齐:
- iOS Safari 的“橡皮筋回弹”会干扰抽屉右滑:给抽屉容器加
touch-action: pan-y,禁用横向拖拽 - 遮罩层点不中:必须用
width: 100vw(不是100%),且z-index比抽屉低一级(如抽屉1000,遮罩999) - 键盘用户卡住:抽屉关闭时要同步设
aria-hidden="true"并遍历子元素加tabindex="-1",打开后立刻menu.focus()


















