flex
属性是flex-grow
,flex-shrink
和flex-basis
的缩写
flex是用在盒子中的子组件的,充分体现了弹性盒子的弹性二字。
例如现在的情况是:
<div class="container">
<div class="item1">Item1</div>
<div class="item2">Item2</div>
<div class="item3">Item3</div>
</div>
在父容器container上开启盒子:
<style>
.container{
display: flex;
width: 1000px;
}
</style>
盒子使用默认方向,主轴是横轴,三个子组件由左到右依次排放。如果此时在子组件上设置了flex属性,那么在横向排放时,子组件的宽度会根据父组件的宽度产生合理的变化,以实现最充分利用父组件宽度的目的。以下都已宽度来说明一下flex-grow
,flex-shrink
和flex-basis的含义。
flex-basis表示了子组件本身(flex-basis设置为auto)或者主动要求的宽度值(一个具体的数字,例如200px,当然根据CSS规则也可以使用百分数例如20%)。
如果父容器在按照三个子组件的flex-basis安排完毕后,宽度仍然有富余,那么此时就意味着子组件可以在flex-basis的基础上变的更宽。那么三个子组件该如何按比例分配这些剩余的宽度,让自己变宽就取决于各自flex-grow的设定。
反之,如果父容器的宽度根本容纳不下三个子组件的flex-basis时,就意味着子组件要在flex-basis的基础上变的更窄。那么三个子组件该如何按比例变窄以弥补父容器在宽度上的“亏欠”,就取决于各自flex-shrink的设定上。
现在为子组件上添加flex属性:
<div class="container">
<div class="item1">Item1</div>
<div class="item2">Item2</div>
<div class="item3">Item3</div>
</div>
<style>
.container{
display: flex;
width: 1000px;
}
.item1 {
height: 100px;
width: 200px;
flex: 2 1 0%;
background:red;
}
.item2 {
height: 100px;
width: 300px;
flex: 2 1 auto;
background:green;
}
.item3 {
height: 100px;
flex: 1 1 200px;
background:blue;
}
</style>
现在三个子组件的flex-basis是0%(也就是0px),auto(也就是自身宽度,300px)和200px,而父容器的宽度足足有1000px,也就意味着有500px的剩余,也就意味着三个子组件是可以变宽的,那么三个子组件该如何按比例来分配这500px呢?
第一个子组件要2份,第二个子组件要2份,第三个子组件要1份,所以第一个组件可以增宽200px,第二个子组件可以增宽200px,第三个子组件可以增宽100px。
最终,当三个子组件在父容器中呈现时,第一个子组件的宽度是200px,第二个子组件的宽度是500px,第三个子组件的宽度是300px。
那现在更改一下父容器的宽度,改成600px,那么按照上面的计算方式,最终三个子组件的宽度应该是:40px,340px和220px,那么实际渲染之后的尺寸确实如此吗?
可以看到,item1的宽度是43.98px,比计算值多了一些;而item2的宽度是337.34px,比计算值要少一些。
我们再把父容器的宽度修改一下,改成500px,那按照计算规则,三个子组件的宽度应该是0px,300px和200px:
可以看到,item1的宽度依然保持在43.98px,而item2的宽度此时已经开始shrink,只有273.61px了。
所以,弹性盒子是有底线的,它的底线就是要保证子元素内容的展示。也就是说如果计算后宽度值小于子元素content的长度时,那么说明该子元素的初始flex-basis设置是不合理的,计算结果不能采纳,弹性盒子会放弃掉计算值而选用该子元素的conten宽度。
所以,在父容器长度为600px的情况,item1的放弃不合理的计算结果40px,采用content宽度43.98px。现在item1的盈余相当于比计算值多了3.98,那这3.98要按比例从item2和item3中扣除,才能保证总长度是600px,按比例,item2扣除3.98的2/3,item3扣除3.98的1/3。
在父容器长度500px的情况下,item1在保证43.98宽度的情况下,父容器反而是亏损的。这个亏损是因为item1的basis值设置不合理导致的。此时要重新计算item2和item3的长度,计算方式是将父容器剩余宽度按照item2和item3的basis比例进行宽度分配。所以,item2的宽度是(500-43.98)*3/5=273.61px,item3的宽度是(500-43.98)*2/5=182.41px。
除了显式的为flex属性赋三个值之外,flex属性的属性值还可以是:
- flex:none
- flex:auto
- flex: 值1
- flex: 值1,值2
- 不设置flex属性
flex:none的含义是0 0 auto,意味着出现grow和shrink的情形时,都不会改变子组件的basis宽度。
flex:auto的含义是1 1 auto
flex只有1个值的时候,要看这个值是数字,是像素还是百分比。
如果是数字,则意味着flex:值1,值,0%
如果是像素或百分比,则意味着flex:1,1,值1
flex有两个值的时候,如果第二个值是数字,则意味着:flex:值1,值2,0%
如果第二个值是像素,则意味着flex:值1,0,值2。
不设置flex意味着使用flex的默认值,意味着flex:0,1,auto。
本文参考了:
Oh My God,CSS flex-basis原来有这么多细节
CSS flex属性深入理解
flex:1 和 flex:auto区别