Flexbox 布局现在已经广泛使用了,我也经常使用。
不过到今天我才知道,原来自己一直以来都有这样一个误区:认为 flex-shrink 的计算机制跟 flex-grow 一样。但其实并不是的。
我们先来看看 flex-grow 的计算机制。
flex-grow
以下面的代码为例:
容器宽度 700px,每个子元素宽度 100px,一共有 3 个子元素。因此,
剩余空间 = 700 - 100 * 3 = 400
也就是说,剩余空间有 400px。接下来就是如何分配这 400px 给 3 个子元素。
首先,计算各项目总的 grow 值:1 + 0 + 3 = 4。
然后按照各个项目的 grow 比例,分配剩余空间:
- 分配给 .green: 1 / 4 * 400 = 100
- 分配给 .yellow: 0 / 4 * 400 = 0
- 分配给 .blue: 3 / 4 * 400 = 300
因此,最终各个项目的宽度如下:
- .green: 100 + 100 = 200
- .yellow: 100 + 0 = 100
- .blue: 100 + 300 = 400
我们来看看是不是这样的:
演示地址:https://codepen.io/zhangbao/pen/LYEZvzZ
果然。
好了,这算回顾一遍 flex-grow 的计算机制了。下面再来看看 flex-shrink 的。
flex-shrink
我再举一个例子,看看 flex-shrink 的情况。
我们先不看最终的呈现效果。先按照 flex-grow 的计算思路计算下 flex-shrink。
错误的计算思路
容器宽度 800px,子元素宽度加起来 900px。就是说两个子元素最终缩减宽度是 900 - 800,也就是 100px。
首先,计算各项目总的 shrink 值:4 + 6 = 10。
然后按照各个项目的 shrink 比例,分配缩减空间:
- 分配给 .green: 4 / 10 * 100 = 40
- 分配给 .yellow: 6 / 10 * 100 = 60
因此,最终各个项目的宽度如下:
- .green: 300 - 40 = 260
- .yellow: 600 - 60 = 540
好了,我们现在看下实际情况。
演示地址:https://codepen.io/zhangbao/pen/yLyJrEW
伤心了,居然一个是 275px,一个是 525 px。.green 缩减了 25px(而不是 40px),.yellow 缩减了 75px(而不是 60px)!
讲了这些,就是为了说明 flex-shrink 的计算机制跟 flex-grow 并不一样。
接下来,我们来看下正确的计算机制是如何的。
正确的计算思路
还是上面的这个例子:
为了计算出每个 Flex 项目的最终宽度。我们需要看几个名词:
- 项目收缩比例宽度(item shrink scaled width)
- 总的收缩比例宽度(total shrink scaled width)
- 收缩比例(shrink ratio)
项目收缩比例宽度
先看公式:
项目收缩比例宽度 = 项目宽度 * 项目的
flex-shrink 值
就是说:
- .green 的收缩比例宽度: 300 * 4 = 1200
- .yellow 的收缩比例宽度: 600 * 6 = 3600
总的收缩比例宽度
先看公式:
总的收缩比例宽度 = 各个项目收缩比例宽度之和
对应本例中的,也就是 1200 + 3600 = 4800。
收缩比例
先看公式:
收缩比例 = 项目收缩比例宽度 / 总的收缩比例宽度
就是说:
- .green 的收缩比例: 1200 / 4800 = 0.25
- .yellow 的收缩比例: 3600 / 4800 = 0.75
这里的 0.25 和 0.25 才是真正的项目收缩比例,而不是之前算出的 0.4(4 / 10) 和 0.6(6 / 10)。
最终的项目宽度
知道了 .green 和 .yellow 的收缩比例,还记得总的缩减宽度吧——100px。接下来,就能计算各项目分配的要缩减的宽度了:
- .green: 100 * 0.25 = 25
- .yellow: 100 * 0.75 = 75
也就是说:
- .green 的最终宽度: 300 - 25 = 275
- .yellow 的最终宽度: 600 - 75 = 525
下面再来看一下这张图,是不是有茅厕顿开的感觉?
参考链接
- https://github.com/samanthaming/Flexbox30
(完)