flex: 1 能撑满剩余空间是因为它是 flex-grow: 1、flex-shrink: 1 和 flex-basis: 0 的简写,其中 flex-basis: 0 使元素初始宽度为0,剩余空间按比例分配。

flex: 1 为什么能撑满剩余空间
flex: 1 是 flex-grow: 1、flex-shrink: 1 和 flex-basis: 0 的简写。关键在 flex-basis: 0 —— 它让元素“假装自己初始宽度为 0”,之后所有剩余空间才按比例分配。如果没设 flex-basis(比如只写 flex: 1 1 auto),它会先按内容宽度占位,再伸缩,结果往往不是你想要的“填满剩余”。
常见错误现象:flex: 1 没生效,右侧还是收缩、换行或溢出;检查父容器是否忘了加 display: flex,或者子元素被 white-space: nowrap 或固定 width 锁死了行为。
- 必须确保父容器有
display: flex且主轴为水平(默认) - 固定侧建议显式设置
width或flex: 0 0 <值>(如flex: 0 0 200px) - 填满侧用
flex: 1即可,不要额外设width: 100%,否则可能冲突 - 若填满侧含内边距或边框,记得加
box-sizing: border-box
左侧固定 200px,右侧自动填满的最小可行代码
这是最常搜到的场景,也是最容易因多写一行而失效的配置。核心就三行 CSS,缺一不可:
container {
display: flex;
}
.sidebar {
flex: 0 0 200px;
}
.main {
flex: 1;
}
使用场景:管理后台侧边栏 + 内容区、聊天窗口联系人列表 + 聊天区。注意 flex: 0 0 200px 比 width: 200px 更稳妥——它明确禁止伸缩,且不受 flex-shrink 影响。
立即学习“前端免费学习笔记(深入)”;
- 别用
float或inline-block混搭,flex 容器里它们会被忽略 - 如果右侧内容超长导致横向滚动,给
.main加min-width: 0(防止 flex item 默认最小宽度为内容宽度) - IE10–11 需要加
-ms-flex: 1前缀,但仅限必要兼容时加
响应式下固定侧变隐藏,填满侧如何不闪跳
用 @media 切换 flex 布局时,常见问题:小屏下固定侧 display: none 后,填满侧突然变宽、内容重排、甚至触发滚动条闪现。根本原因是 flex: 1 在不同父容器宽度下重新计算,而浏览器渲染有延迟。
- 小屏时把固定侧设为
flex: 0 0 0+overflow: hidden+opacity: 0,比直接display: none更平滑 - 填满侧始终设
min-width: 0,避免内容撑开导致布局突变 - 如果用 JS 控制显示/隐藏,优先改 class 而非内联 style,减少重排频率
flex: 1 在表格或表单中为啥不工作
在 <table>、<form> 或某些 UI 库组件(如 Ant Design 的 Form.Item)里直接套 flex: 1,大概率失效。因为这些元素自带 display: table-cell 或 display: block 且内部有强约束样式,flex 不会穿透继承。
- 必须把 flex 容器设在「直接父级」上,而不是表单顶层容器
- 遇到第三方组件,先查文档看是否支持
className或style透传,再包裹一层<div style="display: flex"> - 表单控件(如
<input>)本身不支持flex,需在外层 div 上设flex: 1
复杂点在于,flex 行为高度依赖父容器的尺寸来源——如果父容器宽高未定义(比如靠内容撑开),flex: 1 就找不到“剩余空间”可分。这个前提很容易被忽略,尤其嵌套多层时。










