关键在应对宽度收缩、滚动干扰和断点切换:侧边栏需设 flex-shrink: 0 或 flex: 0 1 240px,主内容用 flex: 1 + min-width: 0,移动端抽屉用 transform 替代 left,统一 box-sizing: border-box 并测试窄屏表现。

直接用 display: flex + flex: 1 就能实现基础联动,但真要“响应”得稳,关键不在布局本身,而在如何应对宽度收缩、滚动干扰和断点切换这三件事。
侧边栏固定宽时,必须设 flex-shrink: 0
很多人写完 .sidebar { width: 240px; } 就以为万事大吉,结果在小屏下侧边栏被压扁——这是因为默认 flex-shrink: 1,容器一窄它就缩。Flexbox 的收缩行为不看 width,只看 flex-shrink 值。
-
flex-shrink: 0是硬性开关,关掉后哪怕容器只剩 100px,侧边栏也死守 240px(溢出由父容器处理) - 如果想让它“可缩但有底线”,改用
flex: 0 1 240px,其中第二个参数是 shrink,第三个是 basis - 别混用
width和flex-basis:同时设时,flex-basis优先级更高,width可能被忽略
主内容区用 flex: 1 而不是 flex-grow: 1
flex: 1 是简写,等价于 flex: 1 1 0,即 grow=1、shrink=1、basis=0。而单独写 flex-grow: 1 会保留默认的 flex-shrink: 1 和 flex-basis: auto,后者容易导致主内容初始宽度取子元素内容宽度,造成意外撑开或收缩。
- 用
flex: 1更干净,明确告诉浏览器:“你随便伸缩,基准就按 0 算” - 如果主内容里有长文本或图片,记得加
min-width: 0,否则 flex item 默认min-width: auto会阻止它收缩到底 - 别给主内容设
width: 100%,它和 flex 冲突,可能让布局卡死
移动端抽屉模式下,transform 比 left 更可靠
媒体查询切到小屏后,侧边栏隐藏+按钮触发滑入,这时动画属性选错会导致高 DPI 屏偏移、缩放失准或渲染抖动。
立即学习“前端免费学习笔记(深入)”;
- 用
transform: translateX(-100%)移出视口,比left: -240px更稳定,因为它不参与文档流计算,也不受 margin/padding 影响 - 滑入时务必同步控制
overflow: hidden在<body>上,否则手指划动仍能滚背景内容,体验断裂 - 遮罩层(backdrop)事件监听必须绑在
document,不能只绑在侧边栏内部——点击空白处关闭是刚需
盒模型细节决定 flex 宽度是否准确
侧边栏加了 padding 或 border 后,实际占宽 = width + padding + border,但 flex-basis 默认按 content-box 计算,容易超出预期。
- 统一加
box-sizing: border-box,让 width 包含 padding 和 border - 如果用了
flex: 0 0 240px,这个 240px 就是最终视觉宽度,无需额外减去内边距 - 别在侧边栏里用
height: 100%控制内部滚动区域——父容器没设 height 时它无效;改用height: calc(100vh - 64px)(减去 header 高度)更稳妥
真正卡住人的从来不是 flex 布局本身,而是收缩逻辑、盒模型计算和移动端滚动穿透这三个点。写完记得在 iPhone Safari 和 Chrome DevTools 的 device toolbar 里拖动宽度反复试,尤其关注 375px 和 414px 这两个典型窄屏宽度下的表现。


















