flex-grow 和 flex-shrink

三葉Leaves Author

先简单理解一下三个概念:

  • flex-basis :Flex 布局引擎在分配空间时,会先计算所有子元素的 flex-basis 之和(如果没有设置,通常就是元素的 width/height 或内容本身的尺寸)。

  • 剩余空间(Positive Free Space):当容器宽度 大于 子元素 flex-basis 总和时,多出来的空间。

  • 溢出空间 / 负空间(Negative Free Space):当容器宽度 小于 子元素 flex-basis 总和时,缺少的空间。

👉 核心口诀:

flex-grow 只在有“剩余空间”时生效,用于决定怎么瓜分多出来的空间。

flex-shrink 只在有“溢出空间”时生效,用于决定怎么缩小自己来分摊欠下的空间。

flex-grow:如何“瓜分奖金”

默认值:0。意思是:不管多出来多少空间,我也不放大。

如果有剩余空间,Flex 引擎会按照子元素 flex-grow 的比例来分配。

公式

元素分配到的空间 = 剩余空间 × (该元素的 flex-grow / 所有兄弟元素的 flex-grow 总和)

最终宽度 = flex-basis + 分配到的空间

案例

假设:容器宽度 500px。包含两个子元素 A 和 B。

  • A 的 flex-basis 为 100px,flex-grow 为 1

  • B 的 flex-basis 为 100px,flex-grow 为 3

  1. 计算剩余空间:500 - (100 + 100) = 300px (这就是要瓜分的奖金)。

  2. 计算总份数:1 + 3 = 4 份。

  3. 计算 A 分到的空间:300px × (1 / 4) = 75px。

  4. 计算 B 分到的空间:300px × (3 / 4) = 225px。

  5. 得出最终宽度:

    • A = 100 + 75 = 175px

    • B = 100 + 225 = 325px

flex-shrink:如何“分摊债务”

它的默认值是 1,意思是“大家一起按比例缩小”。如果设为 0,则表示“宁死不屈,绝不缩小”。

🚨 重点注意: flex-shrink 的计算不是像 flex-grow 那样直接按比例瓜分!它是一个加权计算的过程,权重就是元素的 flex-basis。这是为了:

本身尺寸越大(flex-basis 大)的元素,要承担更多的缩小量(分摊更多的债务)。

所以,它的公式更复杂一点:

公式

  1. 计算总权重 (Total Weight) = Σ (每个元素的 flex-basis × 该元素的 flex-shrink)

  2. 计算元素的收缩因子 (Shrink Factor) = (该元素的 flex-basis × 该元素的 flex-shrink) / 总权重

  3. 元素被扣除的空间 = 溢出空间 (绝对值) × 该元素的收缩因子
    最终宽度 = flex-basis - 被扣除的空间

要理解这个公式很简单。想象如果不加权,那第二步里分母应该就是 flex-shrink 的求和。
而这里为了加权,所以在此基础上多乘了一个 flex-basis 罢了。

案例

假设:容器宽度 400px。包含两个子元素 A 和 B。

  • A 的 flex-basis 为 200px,flex-shrink 为 1

  • B 的 flex-basis 为 300px,flex-shrink 为 2

  1. 计算溢出空间:(200 + 300) - 400 = 100px (这就是要分摊的债务)。

  2. 计算总权重:(A的200 × 1) + (B的300 × 2) = 200 + 600 = 800。

  3. 计算 A 扣除的空间:100px × (200 / 800) = 25px。

  4. 计算 B 扣除的空间:100px × (600 / 800) = 75px。

  5. 得出最终宽度:

    • A = 200 - 25 = 175px

    • B = 300 - 75 = 225px

(你可以看到,虽然 B 的 shrink 只是 A 的 2倍,但因为 B 本身更大,它实际被扣除的空间是 A 的 3倍)

常见的实战问题

flex: 1 是什么?

这其实是一个简写属性,是 flex-grow、flex-shrink 和 flex-basis 的简写。
flex: 1 等同于 flex: 1 1 0%

这意味着元素会占据剩余空间(grow: 1),也会收缩(shrink: 1),最重要的是它的基础尺寸被视为 0。这意味着所有容器空间都被当做“剩余空间”来按比例绝对平分,不受元素内部内容本身宽度的影响。

所以,经常用这个属性来分配子元素在父元素中占据的空间比例。

flex-shrink 没生效,元素还是被撑破了

根据 CSS 规范,Flex items 有一个默认的最小尺寸规则:min-width: auto(如果是横向)。
即使你允许元素 shrink,引擎在计算时,它的缩小极限默认就是它内部内容的最小宽度(min-content)。如果不换行文本太长,min-content 就很大,它就缩不下去。

解决办法:

给这个子元素强行加上 min-width: 0; 或者 overflow: hidden;。这就打破了 min-width: auto 的限制,允许子元素缩小到比其内容还要小,配合 text-overflow: ellipsis 就能实现完美的文字截断。

  • 标题: flex-grow 和 flex-shrink
  • 作者: 三葉Leaves
  • 创建于 : 2026-03-09 00:00:00
  • 更新于 : 2026-03-09 16:45:20
  • 链接: https://blog.oksanye.com/9f4dbe90ccca/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论