关于 flex-grow 和 flex-shrink 的计算

关于 flex-grow 和 flex-shrink 的计算

 

Flex-Grow

容器1 固定宽度为 500px . 子元素 A, B, C 和 F 的 flex-grow 属性为 1 . 子元素 D 和 E 的 flex-grow 的属性为 2 .

<div id="container1">
    <div class="box1" style="background-color:red;">A</div>
    <div class="box1" style="background-color:lightblue;">B</div>
    <div class="box1" style="background-color:yellow;">C</div>
    <div class="box2" style="background-color:brown;">D</div>
    <div class="box2" style="background-color:lightgreen;">E</div>
    <div class="box1" style="background-color:brown;">F</div>
</div>
#container1 {
    display: flex;
    justify-content: space-around;
    flex-flow: row wrap;
    align-items: stretch;
    font-family: monospace;
    font-size: 20px;
    line-height: 28px;
    width: 500px;
    height: 28px;
}

.box1 {
    flex-grow: 1;
}

.box2 {
    flex-grow: 2;
}

 最终显示效果如下:

子元素根据 flex-grow 扩增的规则是,容器的宽度减去子元素的宽度,得到剩余宽度,再按照 flex-grow 的比例进行分配。即使子元素没有指定宽度,子元素中的内容(此例中为英文字符)其实还是需要计算宽度的。计算过程如下:

容器宽度为 500px,每个子元素中的内容宽度为 12px。

剩余宽度为:500px - 6*12px = 428px。

flex-grow 为 1 的子元素在原来 12px 的基础上增加 428px/8 = 53.5px,最终宽度为 65.5px。

flex-grow 为 2 的子元素在原来 12px 的基础上增加 2*428px/8 = 107px,最终宽度为 119px。

 

容器2 固定宽度为 500px . 子元素 A, B, C 和 F 宽度为 50px 并且 flex-grow 属性为 1 . 子元素 D 和 E 未指定宽度,flex-grow 属性为 2。

<div id="container2">
    <div class="box3" style="background-color:red;">A</div>
    <div class="box3" style="background-color:lightblue;">B</div>
    <div class="box3" style="background-color:yellow;">C</div>
    <div class="box4" style="background-color:brown;">D</div>
    <div class="box4" style="background-color:lightgreen;">E</div>
    <div class="box3" style="background-color:brown;">F</div>
</div>
#container2 {
    display: flex;
    justify-content: space-around;
    flex-flow: row wrap;
    align-items: center;
    font-family: monospace;
    font-size: 20px;
    line-height: 28px;
    width: 500px;
    height: 28px;
}

.box3 {
    width: 50px;
    height: 28px;
    flex-grow: 1;
}

.box4 {
    height: 28px;
    flex-grow: 2;
}

最终显示效果如下:

计算过程如下:

容器宽度为 500px,其中4个子元素的宽度设定为 50px,剩余 2 个子元素宽度未设定,但是内容宽度为 12px。

剩余宽度为:500px - 4*50px - 2*12px = 276px。

flex-grow 为 1 的子元素在原来 50px 的基础上增加 276px/8 = 34.5px,最终宽度为 84.5px。

flex-grow 为 2 的子元素在原来 12px 的基础上增加 2*276px/8 = 69px,最终宽度为 81px。

 

小结

子元素最终的显示宽度与 flex-grow 并不成正比。flex-grow 属性值为 2 的子元素宽度不一定是 flex-grow 为 1 的子元素宽度的 2 倍。最终的显示宽度不仅和 flex-grow 属性有关,还和子元素中的内容宽度有关。注意:我特意指定了子元素中的字体为 monospace 等宽字体,每个子元素中只显示一个字母,这样方便计算元素的内容宽度,也有利于排除元素中内容的影响。


Flex-Shrink

 

容器3 的固定宽度为 500px . 子元素 A, B, C 和 F 的宽为 100px, flex-shrink 属性为 1。子元素 D 和 E 的宽为 200px,flex-shrink 属性为 2。

<div id="container3">
    <div class="box5" style="background-color:red;">A</div>
    <div class="box5" style="background-color:lightblue;">B</div>
    <div class="box5" style="background-color:yellow;">C</div>
    <div class="box6" style="background-color:brown;">D</div>
    <div class="box6" style="background-color:lightgreen;">E</div>
    <div class="box5" style="background-color:brown;">F</div>
</div>
#container3 {
    display: flex;
    justify-content: space-around;
    align-items: center;
    font-family: monospace;
    font-size: 20px;
    line-height: 28px;
    width: 500px;
    height: 28px;
}

.box5 {
    width: 100px;
    height: 28px;
    flex-shrink: 1;
}

.box6 {
    width: 200px;
    height: 28px;
    flex-shrink: 2;
}

最终显示效果如下:

如果子元素的宽度加起来超过容器的宽度,那么就需要各子元素按照一定规则进行缩减。计算方法是,先用子元素的宽度总和减去容器宽度,得到溢出宽度,溢出宽度需要各子元素缩减一定比例,而这些比例与子元素的 flex-shrink 属性正相关。计算过程如下:

容器宽度为 500px,4 个子元素的宽度为 100px,2个子元素的宽度为 200ppx。

溢出宽度为:4*100px + 2*200px - 500px = 300px。

设 flex-shrink = 1 的子元素缩减 n (n < 1),那么flex -shrink = 2 的子元素缩减 2n。

flex-shrink = 1 的子元素总共缩减 4*100*npx,flex-shrink = 2 的子元素总共缩减 2*200*2npx。所有子元素缩减的像素要等于溢出宽度。即:

4*100*npx + 2*200*2npx = 300px

解得:n = 0.25

所以,A,B,C,F 4个子元素最终的宽度为 100px * (1 - 0.25) = 75px。D,E 2个子元素最终的宽度为 200px * (1 - 2 * 0.25) = 100px。

 

容器4的固定宽度为 500px . 子元素 A, B, C 和 F 的宽为 100px,flex-shrink 属性为 1。子元素 D 和 E 宽为 200px,最小宽度为 80px,flex-shrink 属性为 2。
 

<div id="container4">
    <div class="box7" style="background-color:red;">A</div>
    <div class="box7" style="background-color:lightblue;">B</div>
    <div class="box7" style="background-color:yellow;">C</div>
    <div class="box8" style="background-color:brown;">D</div>
    <div class="box8" style="background-color:lightgreen;">E</div>
    <div class="box7" style="background-color:brown;">F</div>
</div>
#container4 {
    display: flex;
    justify-content: space-around;
    align-items: center;
    font-family: monospace;
    font-size: 20px;
    line-height: 28px;
    width: 500px;
    height: 28px;
}

.box7 {
    width: 100px;
    height: 28px;
    flex-shrink: 1;
}

.box8 {
    width: 200px;
    min-width: 80px;
    height: 28px;
    flex-shrink: 2;
}

容器5的固定宽度为 500px。子元素 A, B, C 和 F 宽为 100px,and flex-shrink 属性为 1。子元素 D 和 E 宽为 200px,最小宽度为 150px,flex-shrink 属性为 2。

<div id="container5">
    <div class="box9" style="background-color:red;">A</div>
    <div class="box9" style="background-color:lightblue;">B</div>
    <div class="box9" style="background-color:yellow;">C</div>
    <div class="box10" style="background-color:brown;">D</div>
    <div class="box10" style="background-color:lightgreen;">E</div>
    <div class="box9" style="background-color:brown;">F</div>
</div>
#container5 {
    display: flex;
    justify-content: space-around;
    align-items: center;
    font-family: monospace;
    font-size: 20px;
    line-height: 28px;
    width: 500px;
    height: 28px;
}

.box9 {
    width: 100px;
    height: 28px;
    flex-shrink: 1;
}

.box10 {
    width: 200px;
    min-width: 150px;
    height: 28px;
    flex-shrink: 2;
}

容器6的固定宽度为 500px。子元素 A, B, C 和 F 宽为 100px,flex-shrink 属性为 1。子元素 D 和 E 宽为 200px,flex-shrink 属性为 2。但是子元素 D 最小宽度为 150px。

<div id="container6">
    <div class="box11" style="background-color:red;">A</div>
    <div class="box11" style="background-color:lightblue;">B</div>
    <div class="box11" style="background-color:yellow;">C</div>
    <div class="box12" style="background-color:brown;">D</div>
    <div class="box13" style="background-color:lightgreen;">E</div>
    <div class="box11" style="background-color:brown;">F</div>
</div>
#container6 {
    display: flex;
    justify-content: space-around;
    align-items: center;
    font-family: monospace;
    font-size: 20px;
    line-height: 28px;
    width: 500px;
    height: 28px;
}

.box11 {
    width: 100px;
    height: 28px;
    flex-shrink: 1;
}

.box12 {
    width: 200px;
    min-width: 150px;
    height: 28px;
    flex-shrink: 2;
}

.box13 {
    width: 200px;
    height: 28px;
    flex-shrink: 2;
}

以上三个容器(4,5,6)的最终显示效果为:

由上面三个容器可以看到,子元素宽度会优先按照 flex-shrink 进行分配,如果某些子元素分配的宽度小于它们的最小宽度,那么这些子元素宽度将不按照 flex-shrink 规则进行分配,直接使用最小宽度。剩余元素来分担容器的溢出宽度。

我们来计算一下容器6的子容器宽度。如果按照 flex-shrink 规则进行分配,D的宽度应该是100px,超过了它的最小宽度。D就按最小宽度计算,溢出宽度由其他子元素承担。

如果D按照最小宽度计算,那么溢出宽度就变为 4*100px + 150px + 200px - 500px = 250px

设A,B,C,F缩减 n (n &lt; 1),那么E就要缩减 2n。

A,B,C,F一共缩减 4*100npx,E缩减 200*2npx。它们缩减的总宽度等于溢出宽度。即:

4*100npx + 200*2npx = 250px

解得:n = 0.3125

所以,A,B,C,F 4个子元素的宽度分别为 100px * (1 - 0.3125) = 68.75px。E的宽度为 200px * (1 - 2* 0.3125) = 75px。

 

参考文章:

MDN flex-grow

MDN flex-shrink

Understanding flexbox

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值