CSS Flex布局中flex-grow和flex-shrink计算规则

Updated on with 0 views and 0 comments

flex-grow

第一步:计算剩余空间

  • flex-grow的和大于1时:剩余空间 = 父容器宽度 - 子元素总宽度
  • flex-grow的和小于1时:剩余空间 = ( 父容器宽度 - 子元素总宽度 ) * ( flex-grow的和 / 1)

第二步:计算各子元素分配到的空间

  1. 总权重:flex-grow的和
  2. 各个权重:格子flex-grow的值
  3. 分配的空间:剩余空间 * ( 各个权重 / 总权重)

第三步:计算扩张后的总空间

  • 项目宽度 + 分配空间

举例说明

基本结构

<div class="parent">
  <div class="child one"></div>
  <div class="child two"></div>
  <div class="child three"></div>
</div>

flex-group和大于1的情况

.parent{
  display: flex;
  width: 500px;
  height: 100px;
  background-color: #000;
}
.child{
  height: 80px;
}
.one{
  flex-grow: 2;
  width: 120px;
  background-color: red;
}
.two{
  flex-grow: 1;
  width: 150px;
  background-color: green;
}
.three{
  flex-grow: 0;
  width: 200px;
  background-color: blue;
}

计算过程

  1. 剩余空间:500 - (120 + 150 + 200) = 30
  2. 分配到的空间:
    1. one: 30 * (2 / 3) = 20
    2. two: 30 * (1 / 3) = 10
    3. three: 30 * (0 / 3) = 0
  3. 最终大小:
    1. one: 120 + 20 = 140
    2. two: 150 + 10 = 160
    3. three: 200 + 0 = 200

image.png

flex-group和小于1的情况

.one{
  flex-grow: 0.2;
  width: 120px;
  background-color: red;
}
.two{
  flex-grow: 0.1;
  width: 150px;
  background-color: green;
}
.three{
  flex-grow: 0.3;
  width: 200px;
  background-color: blue;
}

计算过程

  1. 剩余空间:(500 - (120 + 150 + 200)) * ((0.2 + 0.1 + 0.3) / 1) = 30 * 0.6 = 18
  2. 分配到的空间:
    1. one: 18 * (0.2 / 0.6) = 6
    2. two: 18 * (0.1 / 0.6) = 3
    3. three: 18 * (0.3 / 0.6) = 9
  3. 最终大小:
    1. one: 120 + 6 = 126
    2. two: 150 + 3 = 153
    3. three: 200 + 9 = 209

image.png


flex-shrink

第一步:计算溢出值(负数)

  • flex-shrink的和大于1时:溢出值 = 父容器宽度 - 子元素总宽度
  • flex-shrink的和小于1时:溢出值 = (父容器宽度 - 子元素总宽度) * (flex-shrink的和 / 1)

第二步:按权重分配溢出值

  1. 总权重:(项目宽度 * flex-shrink) 求和
  2. 各个权重:项目宽度 * flex-shrink
  3. 项目溢出值:总溢出值 * (各个权重 / 总权重)

第三步:计算收缩后的总空间

  • 项目宽度 + 项目溢出值

举例说明

flex-shrink和大于1的情况

.parent{
  display: flex;
  width: 400px;
  height: 100px;
  background-color: #000;
}
.child{
  height: 80px;
}
.one{
  flex-shrink: 2;
  width: 120px;
  background-color: red;
}
.two{
  flex-shrink: 1;
  width: 150px;
  background-color: green;
}
.three{
  flex-shrink: 3;
  width: 200px;
  background-color: blue;
}

计算过程

  1. 溢出值:400 - (120 + 150 + 200) = -70
  2. 各个溢出值:
    • 总权重:120 * 2 + 150 * 1 + 200 * 3 = 990
    • one: -70 * (120 * 2 / 990) = -16.97
    • two: -70 * (150 * 1 / 990) = -10.61
    • three: -70 * (200 * 3 / 990) = -42.42
  3. 最终大小:
    1. one: 120 + (-16.97) = 103.03
    2. two: 150 + (-10.61) = 139.39
    3. three: 200 + (-42.42) = 157.58

image.png

flex-shrink和小于1的情况

.one{
  flex-shrink: 0.2;
  width: 120px;
  background-color: red;
}
.two{
  flex-shrink: 0.1;
  width: 150px;
  background-color: green;
}
.three{
  flex-shrink: 0.3;
  width: 200px;
  background-color: blue;
}

计算过程

  1. 溢出值:(400 - (120 + 150 + 200)) * ((0.2 + 0.1 + 0.3) / 1)= -70 * 0.6 = -42
  2. 各个溢出值:
    • 总权重:120 * 0.2 + 150 * 0.1 + 200 * 0.3 = 99
    • one: -42 * (120 * 0.2 / 99) = -10.18
    • two: -42 * (150 * 0.1 / 99) = -6.36
    • three: -42 * (200 * 0.3 / 99) = -25.45
  3. 最终大小:
    1. one: 120 + (-10.18) = 109.82(这里和Chrome浏览器实际结果差0.01,等查明计算规则后写明)
    2. two: 150 + (-6.36) = 143.64
    3. three: 200 + (-25.45) = 174.55

image.png

总结

差异宽度的计算(第一步中的值的计算)

  • 如果所有元素的 flex-grow/shrink 之和大于等于 1,则所有子元素的尺寸一定会被调整到适应父元素的尺寸(在不考虑 max/min-width/height 的前提下)即 父容器宽度 - 子元素总宽度
  • 而如果 flex-grow/shrink 之和小于 1,则只会 grow 或 shrink 所有元素 flex-grow/shrink 之和相对于 1 的比例。即 (父容器宽度 - 子元素总宽度) * (flex-grow/shrink 之和 / 1)

权重的计算(第二步中值的计算)

  • grow 时的每个元素的权重即为元素的 flex-grow 的值;即 各个扩张因子/扩张因子的和
  • shrink 时每个元素的权重则为元素 flex-shrink 乘以 width 后的值;即 (收缩因子 * 项目宽度)/ ((收缩因子 * 项目宽度)的和)

补充:flex-shrink和<1时计算结果和实际渲染结果

计算结果109.82143.64174.55
Chrome Mac屏幕109.82143.63174.55
Chrome 其他屏幕109.81143.64174.55
Safari110144175

标题:CSS Flex布局中flex-grow和flex-shrink计算规则
作者:lj0812
地址:https://blog.hereis.me/articles/2020/05/27/1590575852573.html