Flex布局的基础以及其他属性,请参考上篇:https://blog.csdn.net/joyce_lcy/article/details/86544661 。
为什么会把这个部分抽出来单独作为一篇呢?因为这三个属性不太容易理解并且需要搭配在一起使用。
剩余空间:是父容器在主轴上可以被项目瓜分的空间。
以下图为例,黑色边框是父容器,ABC是项目。白色区域为剩余空间,300px - 50px - 80px - 50px = 120px,计算公式如下:
剩余空间 = container.with - A.width - B.width - C.width
<ul>
<li class="a">Ali>
<li class="b">Bli>
<li class="c">Cli>
ul>
ul{
display: flex;
width: 300px;
border: solid 1px black;
}
li{
list-style: none;
width: 50px;
height: 50px;
text-align: center;
line-height: 50px;
}
.a{
background-color: wheat;
}
.b{
background-color: lightcoral;
width: 80px;
}
.c{
background-color: lightblue;
}
定义项目的放大比例,默认为0。
从上例中可以知道,虽然有剩余空间,但是并没有被项目所瓜分。这是因为默认的放大比例为0,如果设置项目的flex-grow(大于0),就会按照比例进行放大。
上例中的容器宽度为300px,剩余空间为120px。
1)只有A设置了flex-grow为1,则A分到全部剩余空间,原本50px的宽度,变为170px
A | B | C | |
---|---|---|---|
flex-grow | 1 | ||
瓜分比例 | 100% | ||
瓜分宽度 | 120px | ||
项目设置宽度 | 50px | 80px | 50px |
项目实际宽度 | 170px | 80px | 50px |
2)ABC都设置了flex-grow,所以按照1:1:2都参与瓜分剩余空间
A | B | C | |
---|---|---|---|
flex-grow | 1 | 1 | 2 |
瓜分比例 | 25% | 25% | 50% |
瓜分宽度 | 30px | 30px | 60px |
项目设置宽度 | 50px | 80px | 50px |
项目实际宽度 | 80px | 110px | 110px |
示例:https://jsfiddle.net/hwvsr13m/1/
定义在分配多余空间之前,项目占据的主轴空间,默认为auto。
是不是很难理解?实际就是设置项目宽度,会覆盖width。
1)设置B的flex-basis为120px,覆盖了原先设置的80px宽度,剩余空间变为80px,全部分配给A。
A | B | C | |
---|---|---|---|
flex-grow | 1 | ||
项目设置宽度 | 50px | 80px | 50px |
flex-basis | 120px | ||
瓜分比例 | 100% | ||
瓜分宽度 | 80px | ||
项目实际宽度 | 130px | 120px | 50px |
2)BC都设置了flex-basis分别为20%和30%,容器宽度为300px,所以被设置为了60px和90px。剩余空间为100px(300 - 50 - 60 - 90),再按照比例瓜分。
A | B | C | |
---|---|---|---|
flex-grow | 1 | 1 | 2 |
项目设置宽度 | 50px | 80px | 50px |
flex-basis | 20%(60px) | 30%(90px) | |
瓜分比例 | 25% | 25% | 50% |
瓜分宽度 | 25px | 25px | 50px |
项目实际宽度 | 75px | 85px | 140px |
示例:https://jsfiddle.net/g2ran6yt/1/
定义项目的缩小比例,默认为1,不允许为负,值越大收缩越多。若值为0,表示不进行缩小。
在上述例子中,项目的宽度总和总是小于容器宽度(即有剩余空间可以被瓜分)。但是,如果大于容器宽度会如何?
1)不设置放大缩小比例,flex-shrink默认缩小比为1:1:1。
剩余空间 = 300 - 80 - 160 - 80 = -20,即总共需要缩小20px。
定义缩小率为x,则80 * x + 160 * x + 80 * x = 20,得到 x = 0.0625。
则,AC缩小5px(0.0625 * 80),B缩小10px(0.0625 * 160)
A | B | C | |
---|---|---|---|
flex-shrink(默认值) | 1 | 1 | 1 |
项目设置宽度 | 80px | 160px | 80px |
缩小率 | 0.0625 | 0.0625 | 0.0625 |
缩小宽度 | 5px | 10px | 5px |
项目实际宽度 | 75px | 150px | 75px |
2)设置B的flex-shrink为2,ABC的缩小比例为1:2:1。
剩余空间 = 300 - 100 - 150 - 100 = -50,即总共需要缩小50px。
定义A和C的缩小率为x,B缩小率为y。y = 2 * x,100 * x + 150 * y + 100 * x = 50。解后得x = 0.1,y = 0.2。
则AC缩小10px(0.1 * 100),B缩小30px(0.2 * 150)
A | B | C | |
---|---|---|---|
flex-shrink | 1(默认值) | 2 | 1(默认值) |
项目设置宽度 | 100px | 150px | 100px |
缩小率 | 0.1 | 0.2 | 0.1 |
缩小宽度 | 10px | 30px | 10px |
项目实际宽度 | 90px | 120px | 90px |
示例:https://jsfiddle.net/jx2dtber/
3)设置A的flex-shrink为2,B的flex-shrink为0,ABC的缩小比例为2:0:1。
剩余空间 = 300 - 100 - 130 - 100 = -30,即总共需要缩小30px。
定义C的缩小率为x,A缩小率为y。y = 2 * x,100 * y + 100 * x = 30。解后得x = 0.1,y = 0.2。
则A缩小20px(0.2 * 100),C缩小10px(0.1 * 100),B宽度不变。
A | B | C | |
---|---|---|---|
flex-shrink | 2 | 0 | 1(默认值) |
项目设置宽度 | 100px | 130px | 100px |
缩小率 | 0.2 | 0 | 0.1 |
缩小宽度 | 20px | 0 | 10px |
项目实际宽度 | 80px | 130px | 90px |
示例:https://jsfiddle.net/1a9jus4e/
上述三个属性之间有着密切的关系,于是有了flex属性,作为flex-grow, flex-shrink 和 flex-basis的简写,后两个属性可选。
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
建议优先使用这个属性,而不是单独写三个分离属性