抽屉动画不能只靠 display: none 切换,因其会移除渲染流导致无法过渡尺寸;需用 visibility、opacity 和 flex-basis 组合控制,并设 flex-shrink: 0 防撑开主内容,transition 仅限 flex-basis 和 opacity,body 冻结滚动需 overflow + touch-action + scrollTop 同步。

抽屉动画为什么不能只靠 display: none 切换?
因为 display: none 会直接移除元素的渲染流,导致无法对 width、height 或 transform 做过渡动画——浏览器根本不会计算它的尺寸变化。抽屉要“拉出来”,必须始终在文档流中(哪怕不可见),靠 visibility + opacity + 尺寸控制组合实现。
Flexbox 容器里侧边栏如何避免撑开主内容区?
关键在父容器用 display: flex 后,子项默认会按内容伸缩。侧边栏必须显式设 flex-shrink: 0,否则当它从 0px 拉伸到 280px 时,主内容区会被压缩变形。同时主内容区要用 flex: 1 占满剩余空间,而不是 flex: auto。
-
sidebar { flex: 0 0 0; width: 0; overflow: hidden; }—— 初始收起状态 -
sidebar.open { flex-basis: 280px; width: 280px; }—— 拉开后固定宽度 - 主内容区写成
main { flex: 1; min-width: 0; },min-width: 0防止文字溢出
transition 该写哪些属性才不卡顿?
只过渡 flex-basis 和 opacity,别碰 width。因为 Flexbox 中 flex-basis 是布局属性,浏览器能高效合成;而直接改 width 在 flex 容器里可能触发重排。同时加 will-change: flex-basis 提前提示渲染引擎优化。
- 推荐写法:
transition: flex-basis 0.3s ease, opacity 0.3s ease; - 收起时加
opacity: 0配合pointer-events: none,避免鼠标穿透误触 - 别写
transition: all,会导致所有属性都参与过渡,包括没变的margin或padding,反而拖慢性能
移动端点击遮罩层关闭抽屉时,如何防止滚动穿透?
抽屉打开时,body 滚动必须冻结,否则背景内容还在动,视觉割裂感极强。单纯 overflow: hidden 在 iOS Safari 上经常失效,得配合 touch-action: none 和记录 scrollTop 值手动还原。
立即学习“前端免费学习笔记(深入)”;
- 打开抽屉:
document.body.style.overflow = 'hidden'; document.body.style.touchAction = 'none'; - 关闭时不仅要恢复
overflow,还得document.body.scrollTop = savedScrollTop; - 更稳妥的做法是给 body 加 class:
body.drawer-open { overflow: hidden; position: fixed; width: 100%; },靠定位锚定视口
抽屉动画的复杂点不在 Flexbox 布局本身,而在“收起态”和“展开态”的尺寸、可见性、交互权限三者必须严格同步——漏掉任意一个,就会出现闪跳、点击失效或背景滚动。


















