本文契机来自于 前端面试题合集 中的 155题 与 156题 ,解答思路也大多来源于此。
笔者个人而言,比较容易理解“扩”的例子,所以先来总结“缩”
当子项的flex-basis总和超过父项宽,则flex-shrink生效(缩)
<div class="container">
<div class="left"></div>
<div class="right"></div>
</div>
<style type="text/css">
* {
padding: 0;
margin: 0;
}
.container {
width: 600px;
height: 300px;
display: flex;
}
.left {
flex: 1 2 500px;
background: red;
}
.right {
flex: 2 1 400px;
background: blue;
}
/*
溢出:500+400-600=300
总权重: 500*2 + 400*1=1400
left收缩比例:(500*2)/1400 ≈ 0.7143
right收缩比例:400/1400 ≈ 0.2857
left收缩宽度:0.7143 × 300 = 214.29
right收缩宽度:0.2857 × 300 = 85.71
left 最终宽度:500 - 214.29 = 285.71
right 最终宽度:400 - 85.71 = 314.29
*/
</style>
公式:
子项的收缩宽度 = 子项收缩比例 × 溢出宽度
子项收缩比例 = (子项宽度 × 子项收缩系数) ÷ 所有子项的(宽度 × 收缩系数)之和
其中,子项收缩系数
即简写flex中的flex-shrink的值
对于注释中的讲解,连写结果即:
left最终宽度 = 500 - (500+400-600) x [ (500 x 2) / (500 x 2 + 400 x 1) ]
=500 - 300 x 1000 / 1400
≈ 285.71
right最终宽度 = 400 - (500+400-600) x [ (400 x 1) / (500 x 2 + 400 x 1) ]
=400 - 300 x 400 / 1400
≈ 314.29
当子项的flex-basis总和小于父项宽,则flex-grow生效(扩)
注:关于特殊值,其中0%即0宽度,auto即对应本身width,比如
{ width: 140px;flex: 2 1 0%;} 的flex-basis是0,而{ width: 100px;flex: 2 1 auto;}的flex-basis是100px。本项注意点来源于flex属性设置详解
<div class="container">
<div class="flex"></div>
<div class="flex"></div>
<div class="flex"></div>
</div>
<style type="text/css">
.container{
display: flex;
width: 540px;
background: red;
height: 50px;
}
/* 540-100-100-100=240剩余空间*/
.container>.flex:nth-child(1){
background: plum;
flex: 1 1 100px;
/* 240*(1/(1+2+3))=40
100+40=140 */
}
.container>.flex:nth-child(2){
background: green;
flex: 2 1 100px;
/* 240*(2/(1+2+3))=80
100+80=180 */
}
.container>.flex:nth-child(3){
background: yellow;
flex: 3 2 100px;
/* 240*(1/2)=120
100+120=220 */
}
</style>
剩余空间分配公式:
分配到的剩余空间宽度 = 剩余空间宽度 * (自身元素的 flex-grow 值 / 所有元素的 flex-grow 值的和)
题外话
对于css中的flex和grid各种五花八门的奇淫技巧层出不穷,当笔者长久止步于似懂非懂的救急应用。此前在使用flex布局时,就经常选择性跳过了flex属性了解,如今一通查询测试下来,也不是那么难以理解。