父容器必须设 display: flex,否则子项 flex 行为无效;首尾项应设 flex: 0 0 auto,中间项设 flex: 1 并加 min-width: 0;间距用 gap 而非 margin。

父容器必须设 display: flex,否则所有子项的 flex 行为无效
很多人写了 flex: 1 却没效果,第一反应是“代码写错了”,其实根本原因是父容器漏了 display: flex。Flex 是父子协同机制:只给子项加 flex 属性,就像只给螺丝拧劲儿却不固定底座——完全不生效。
常见错误现象:
中间项宽度为 0、三列挤成一列、内容溢出、对齐错乱。
正确做法是:
- 父容器显式声明
display: flex(推荐块级,即display: flex而非inline-flex) - 确认
flex-direction是默认的row(横向主轴),否则flex: 1会作用在高度上 - 避免父容器同时设
width: 100%+padding未用box-sizing: border-box,这会导致内部可用宽度不足
flex: 1 只能用于中间项,首尾项要明确禁用伸缩
想让左右固定、中间自适应,本质是“中间项抢走所有剩余空间,首尾项按需占位”。但若首尾项也写 flex: 1,三者就会平分——这不是你想要的。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 首项和尾项设
flex: 0 0 auto(等价于flex-shrink: 0; flex-grow: 0; flex-basis: auto),确保它们不伸缩、不收缩、按内容宽占位 - 中间项设
flex: 1(即flex-grow: 1; flex-shrink: 1; flex-basis: 0%),从 0 开始均分剩余空间,严格等分逻辑才成立 - 如果首尾项本身有
width(比如width: 80px),必须删掉或覆盖为flex-basis: 80px,否则 width 会与 flex 冲突
内容撑开导致中间项不占满?加 min-width: 0
当中间项内含长英文、URL、img 或 inline-block 元素时,浏览器默认阻止压缩,flex: 1 就会失效——看着像“没生效”,其实是被内容撑开了。
这是最常被忽略的隐藏坑。解决方案很简单:
- 给中间项加
min-width: 0,放开最小宽度限制,允许 Flex 引擎把内容“挤进去” - 如果还用了
overflow: hidden或text-overflow: ellipsis,必须同步加white-space: nowrap,否则换行会干扰 flex 计算 - 不要依赖
word-break: break-all来救急——它破坏可读性,且在某些 Android WebView 下表现不稳定
间距用 gap,别碰 margin
想实现“左侧按钮 + 20px 间隙 + 中间内容 + 20px 间隙 + 右侧按钮”,有人会尝试给首尾项加 margin,结果总宽度超限、换行或右侧消失。
原因:margin 是外边距,参与盒模型计算;而 gap 是容器级间距,不侵占项目空间,不影响 flex 分配逻辑。
- 现代浏览器(Chrome 84+、Firefox 63+、Safari 14.1+)直接用
gap: 20px - 需要兼容旧环境(如 IE 或老版 WebView)时,改用 padding 包裹整个容器,并在外层加负 margin 抵消,或套一层 wrapper 控制内边距
- 绝对避免
width: calc(33.333% - 10px)+margin组合——四舍五入误差在某些 Android WebView 下会引发布局抖动
真正难的不是写对 flex: 1,而是理解它背后那套“基线→增长→收缩”的三方博弈逻辑。首尾固定中间等分看着简单,但只要漏掉 min-width: 0 或父容器没设 display: flex,就全盘失效。



















