CSS属性 flex-shrink 实现自适应的计算公式
目录
- CSS属性 flex-shrink 实现自适应的计算公式
-
- 前提
- 问题起源
- 三个子容器使用flex-shrink计算比例
-
- 1、常规计算
- 2、便捷计算
- 扩展
-
- 1、两个子容器时
- 2、四个子容器时
- ...
前提
在读这篇文章前,你必须对css的flex属性有些了解,并知道flex-shrink的计算方式。
- 你可以看阮一峰的flex布局教程,或者去w3cschool了解flex
- 关于flex-shrink的计算,我比较推荐这篇文章《深入理解 flex 布局以及计算_Flexbox, Layout》。PS:它感谢的那几篇文章也可以看看
问题起源
我在写布局的时候要用flex,页面是要做自适应的。因本人刚接触flex,所以这flex并没有按照我想要的效果来。页面在放大和缩小的时候总是不对劲,可能是因为我自作聪明,没有去了解flex-grow和flex-shrink的计算方式,以为那个比例是按照页面最后大小来占比的。后来我就去啃这两个东西,发现flex-grow的计算方式和我想的差不多,flex-shrink的计算却是不一样的,所以就去找将这flex-shrink的比例转换为页面最后大小的占比。
三个子容器使用flex-shrink计算比例
1、常规计算
假设f为父容器的宽,a为子容器A的flex-shrink,b为子容器B的flex-shrink,c为子容器C的flex-shrink,图为计算前容器摆放情况(忽略margin和padding)。最重要的条件是子容器的flex-basis = 100%,没有padding,margin等固定的东西。
由条件可知,超出部分是2f,权重和是af+bf+cf=(a+b+c)faf+bf+cf = (a+b+c)faf+bf+cf=(a+b+c)f
A将缩小 af/(a+b+c)f?2faf/(a+b+c)f*2faf/(a+b+c)f?2f
A最后的结果是 f?af/(a+b+c)f?2ff-af/(a+b+c)f*2ff?af/(a+b+c)f?2f
B将缩小 bf/(a+b+c)f?2fbf/(a+b+c)f*2fbf/(a+b+c)f?2f
B最后的结果是 f?bf/(a+b+c)f?2ff-bf/(a+b+c)f*2ff?bf/(a+b+c)f?2f
C将缩小 cf/(a+b+c)f?2fcf/(a+b+c)f*2fcf/(a+b+c)f?2f
C最后的结果是 f?cf/(a+b+c)f?2ff-cf/(a+b+c)f*2ff?cf/(a+b+c)f?2f
所以
Ae:Be:Ce=(b+c?a):(a+c?b):(a+b?c)Ae:Be:Ce=(b+c-a):(a+c-b):(a+b-c) Ae:Be:Ce=(b+c?a):(a+c?b):(a+b?c)
所以只要知道Ae、Be、Ce(子容器最终占页面的比例),这问题就变成了三元一次方程了。
ps:这只适用三个子容器的情况,当容器增加,就会变成n元一次方程,计算会加大。
2、便捷计算
当条件和上述的一样时,根据比例的特性,可得
2Ae:2Be:2Ce=(b+c?a):(a+c?b):(a+b?c)2Ae:2Be:2Ce=(b+c-a):(a+c-b):(a+b-c) 2Ae:2Be:2Ce=(b+c?a):(a+c?b):(a+b?c)
即
{2Ae=b+c?a=a+b+c?2a2Be=a+c?b=a+b+c?2b2Ce=a+b?c=a+b+c?2c\left\{\begin{matrix} 2Ae=b+c-a=a+b+c-2a \\ 2Be=a+c-b=a+b+c-2b \\ 2Ce=a+b-c=a+b+c-2c \end{matrix}\right. ????2Ae=b+c?a=a+b+c?2a2Be=a+c?b=a+b+c?2b2Ce=a+b?c=a+b+c?2c?
得
{Ae=a+b+c2?aBe=a+b+c2?bCe=a+b+c2?c\left\{\begin{matrix} Ae=\frac{a+b+c}{2}-a \\ Be=\frac{a+b+c}{2}-b \\ Ce=\frac{a+b+c}{2}-c \end{matrix}\right. ????Ae=2a+b+c??aBe=2a+b+c??bCe=2a+b+c??c?
所以
Ae:Be:Ce=a+b+c2?a:a+b+c2?b:a+b+c2?cAe:Be:Ce=\frac{a+b+c}{2}-a:\frac{a+b+c}{2}-b:\frac{a+b+c}{2}-c Ae:Be:Ce=2a+b+c??a:2a+b+c??b:2a+b+c??c
到这,这比例计算就简便多了。
扩展
对简便计算做下扩展
1、两个子容器时
Ae:Be:Ce=(a+b)?a:(a+b)?bAe:Be:Ce=(a+b)-a:(a+b)-b Ae:Be:Ce=(a+b)?a:(a+b)?b
2、四个子容器时
Ae:Be:Ce:De=a+b+c+d3?a:a+b+c+d3?b:a+b+c+d3?c:a+b+c+d3?dAe:Be:Ce:De=\frac{a+b+c+d}{3}-a:\frac{a+b+c+d}{3}-b:\frac{a+b+c+d}{3}-c:\frac{a+b+c+d}{3}-d Ae:Be:Ce:De=3a+b+c+d??a:3a+b+c+d??b:3a+b+c+d??c:3a+b+c+d??d
…
此时,可看出有n个子容器时,便捷比例计算公式是
Ae:Be...Me=a+b...mn?1?a:a+b...mn?1?b...a+b...mn?1?mAe:Be...Me=\frac{a+b...m}{n-1}-a:\frac{a+b...m}{n-1}-b...\frac{a+b...m}{n-1}-m Ae:Be...Me=n?1a+b...m??a:n?1a+b...m??b...n?1a+b...m??m
最后在提醒一次:子容器的flex-basis = 100%,没有padding,margin等固定的东西