flex-shrink默认值为1,表示弹性子项在空间不足时按比率收缩;Bootstrap栅格类默认启用该行为,导致小屏下列变窄,可通过.flex-shrink-0禁用。

flex-shrink 默认值是 1,不是“不收缩”
很多人以为 Bootstrap 的弹性子项(比如 .col)在小屏下“突然变窄”是 bug,其实是 flex-shrink: 1 在起作用——它允许子项主动压缩自身宽度来适应容器。Bootstrap 4/5 所有基于 display: flex 的栅格类(如 .row、.d-flex)都继承该默认行为。
常见错误现象:.col-6 .col-6 在超小屏下挤成两列窄条、文字换行、图标被压扁;或者用 .w-100 强制设宽却失效。
-
flex-shrink: 0可禁用收缩,但必须加在子项上(如.col.flex-shrink-0),不能只改父容器 - Bootstrap 5 提供了工具类
.flex-shrink-0和.flex-shrink-1,直接可用,无需自定义 CSS - 慎用
flex-shrink: 0配合固定width:若内容超长,会导致横向溢出或触发滚动条,而非折行
flex-shrink 和 flex-grow 同时存在时,谁先算?
计算顺序不是“先 grow 再 shrink”,而是按 Flex 基线算法统一处理:先用 flex-basis(或 width)确定初始尺寸,再根据剩余空间正负决定执行 grow 还是 shrink。当容器宽度小于所有子项 flex-basis 总和时,flex-shrink 才真正介入。
使用场景举例:侧边栏 + 主内容区布局中,希望侧边栏固定 240px、主内容区填满剩余并可收缩——此时要给侧边栏设 flex-shrink: 0,主内容区设 flex-grow: 1 且 flex-shrink: 1(默认)。
- 如果主内容区也设
flex-shrink: 0,小屏下会横向溢出,而不是缩小字体或隐藏部分 UI -
flex-basis比width优先级高;设了flex-basis: 200px后,width就不再影响主轴尺寸 - Bootstrap 5 的
.col类内部用了flex: 0 1 auto,即flex-grow: 0、flex-shrink: 1、flex-basis: auto,所以它默认不拉伸、但会收缩
flex-shrink 导致的兼容性陷阱
老版本 Safari(iOS 13.3 / macOS 10.15.3 之前)对 flex-shrink 计算有偏差,尤其当子项含 min-width 或内联元素时,可能出现收缩不足或过度压缩。这不是 Bootstrap 的问题,而是浏览器实现差异。
真实报错不会抛异常,但你会看到:同一套 .row > .col 在 Chrome 正常,在 Safari 中最后一列明显窄于其他列,或文字被截断无省略号。
- 降级方案:对关键区域加
min-width: 0(重置 flex 项最小尺寸限制),能缓解多数 Safari 收缩异常 - 避免混用
flex-shrink和white-space: nowrap——后者会阻止换行,而前者又强行压缩,极易触发不可见溢出 - Bootstrap 5 官方已放弃对 Safari flex-shrink 行为做 polyfill,文档明确建议用
min-width: 0或重构为grid布局替代
什么时候该关掉 flex-shrink?
不是所有弹性容器都需要收缩能力。关闭 flex-shrink 是明确的设计选择,不是“修复”。关键看内容是否允许被视觉压缩。
典型适用场景:按钮组、标签页导航、带图标的工具栏、固定宽度的表单控件组。
- 用
.d-flex .flex-nowrap+.flex-shrink-0组合,比单设flex-shrink: 0更安全(flex-nowrap阻止换行,flex-shrink-0阻止压缩) - 不要全局覆盖
* { flex-shrink: 0 }——这会让所有弹性子项失去响应能力,包括 Bootstrap 内部的.navbar-nav、.btn-group - 注意
flex-shrink: 0对gap无影响,但 gap 本身会从容器总宽中扣除;若同时禁用 shrink 又设大 gap,可能直接撑破容器
实际最易被忽略的一点:flex-shrink 不是“让元素变小”的开关,它是“允许父容器在空间不足时,按权重拿走子项主轴空间”的协商机制。关掉它,等于把尺寸控制权完全交还给子项自身——这时候你得自己管好 min-width、overflow 和内容流。











