当前,大家最常用的css布局是flex布局,如果还不了解这个,请百度阮一峰+flex,阮老师的文章对于flex的语法讲得比较清楚,同时也给出了几个很好的实例,对于初学者非常有益处。这里主要理一理flex布局中几个不那么常用的属性:flex-grow, flex-shrink, flex-basis。最后再理一下flex属性在不同的取值情况下,flex-grow, flex-shrink, flex-basis分别取值是多少。
1. flex-grow瓜分父项“剩余空间”
这个输出结果是下面这段代码生成的。
<div class="box">
<div class="box-item">A: width 100</div>
<div class="box-item">BB: width 100</div>
<div class="box-item">CCC: width 100</div>
</div>
<style>
.box {
width: 600px;
height: 100px;
display: flex;
background-color: #E2E2E2;
}
.box-item {
height: 100px;
}
.box-item:nth-child(1){
width: 100px;
background: red;
}
.box-item:nth-child(2){
width: 100px;
background: green;
}
.box-item:nth-child(3){
width: 100px;
background: grey;
}
</style>
A,B,C的宽度都是100px,而父容器的宽度是600px。这就产生了“剩余空间”。“剩余空间”的大小是:600 - 100 - 100 - 100 = 300px,也就是说,“剩余空间”等于父容器的宽度减去所有子容器的宽度。 如果子容器使用了flex-grow属性,那么这个“剩余空间”就会被使用了flex-grow属性的子容器去“占领”。默认情况下,flex-grow的值是0,也就是说不会去占领“剩余空间”,就让剩余的地方空着。 如果多个子容器设置了flex-grow的值,那么“剩余空间”是怎样被子容器占领的呢?看下面的代码:
<div class="box">
<div class="box-item">A: width 100</div>
<div class="box-item">BB: width 100</div>
<div class="box-item">CCC: width 100</div>
</div>
<style>
.box {
width: 600px;
height: 100px;
display: flex;
background-color: #E2E2E2;
}
.box-item {
height: 100px;
}
.box-item:nth-child(1){
width: 100px;
background: red;
}
.box-item:nth-child(2){
width: 100px;
background: green;
flex-grow: 1;
}
.box-item:nth-child(3){
width: 100px;
background: grey;
flex-grow: 2;
}
</style>
A的flex-grow是默认值0,B设置的是1,C设置的是2,而整个“剩余空间”的大小是300px。计算过程如下:
| 宽度 | flex-grow | 占领值 | 实际值 | |
|---|---|---|---|---|
| A | 100px | 0(默认) | 0 / ( 0 + 1 + 2) * 300 = 0px | 0 + 100 = 100px |
| B | 100px | 1 | 1 / ( 0 + 1 + 2) * 300 = 100px | 100 + 100 = 200px |
| C | 00px | 2 | 2 / ( 0 + 1 + 2) * 300 = 200px | 200 + 100 = 300px |
实际效果如下:
2. flex-shrink吸收父项“溢出空间”
先用如下代码,设置A, B, C宽度都是200px。
<div class="box">
<div class="box-item">A: width 200</div>
<div class="box-item">BB: width 200</div>
<div class="box-item">CCC: width 200</div>
</div>
<style>
.box {
width: 600px;
height: 100px;
display: flex;
background-color: #E2E2E2;
}
.box-item {
height: 100px;
}
.box-item:nth-child(1){
width: 200px;
background: red;
}
.box-item:nth-child(2){
width: 200px;
background: green;
}
.box-item:nth-child(3){
width: 200px;
background: grey;
}
</style>
看到效果如下:
然后调整父容器的宽度为400px。这样A,B,C就的宽度之和为600px,大于父容器的400px。这时A,B,C都会被压缩。这里控制压缩的就是flex-shrink这个属性,默认情况下flex-shrink为1,将flex-shrink设为0时,不压缩。
看一看下面的代码会是什么效果?
<div class="box">
<div class="box-item">A: width 200</div>
<div class="box-item">BB: width 200</div>
<div class="box-item">CCC: width 200</div>
</div>
<style>
.box {
width: 400px;
height: 100px;
display: flex;
background-color: #E2E2E2;
}
.box-item {
height: 100px;
}
.box-item:nth-child(1){
width: 200px;
background: red;
}
.box-item:nth-child(2){
width: 200px;
background: green;
flex-shrink: 1;
}
.box-item:nth-child(3){
width: 200px;
background: grey;
flex-shrink: 2;
}
</style>
计算如下: 首先“溢出空间”大小为:600 - 400 = 200px
| 宽度 | flex-shrink | 总压缩权重 | 压缩率 | 宽度 | |
|---|---|---|---|---|---|
| A | 200px | 1(默认) | 1200 + 1200 + 2*200 = 800 | 1 * 200 / 800 = 0.25 | 200 - 0.25 * 200 = 150px |
| B | 200px | 1 | 1 * 200 / 800 = 0.25 | 200 - 0.25 * 200 = 150px | |
| C | 200px | 2 | 2 * 200 / 800 = 0.5 | 200 - 0.5 * 200 = 100px |
实际效果如下:
3. flex-basis优先级高于width
如果子容器同时设置了width与flex-basis属性,那么flex-basis优先,这个非常好理解,看如下代码:
<div class="box">
<div class="box-item">A: width 200</div>
<div class="box-item">BB: width 200</div>
<div class="box-item">CCC: width 200, flex-basis 100</div>
</div>
<style>
.box {
width: 600px;
height: 100px;
display: flex;
background-color: #E2E2E2;
}
.box-item {
height: 100px;
}
.box-item:nth-child(1){
width: 200px;
background: red;
}
.box-item:nth-child(2){
width: 200px;
background: green;
}
.box-item:nth-child(3){
width: 200px;
flex-basis: 100px;
background: grey;
}
</style>
对于C,设置了flex-basis为100px,而width为200px,最终,效果是C的width为100px,如下图所示:
flex-basis默认是auto,也就是容器原本的大小。 当 flex-basis 值为 0% 时,是把该容器视为零尺寸的。
4. flex是flex-grow,flex-shrink,flex-basis的集合体
上面这三个属性,其实我们在实际开发中并不常见。这是因为我们用flex这个属性来表达了上面三个属性。 flex是flex-grow, flex-shrink, flex-basis的组合体,若上面三个值都取默认,则flex的值为0 1 auto。 flex有两个快捷值: auto(1 1 auto)和none(0 0 auto)。 前者代表等比例伸缩,后者代表不伸缩,这也是我们实际开发中常用的两个值。
5. flex究竟代表啥?
但是实际flex可以取的值却非常的多,下面分别按情况列出如下:
| flex取值 | 等价flex-grow | 等价flex-shrink | 等价flex-basis |
|---|---|---|---|
| 非负数字x | x | 1 | 0% |
| 0 | 0 | 1 | 0% |
| 长度或百分比x | 1 | 1 | x |
| 两个非负数x y | x | y | 0% |
| 一个非负数x和一个长度或者百分比y | x | 1 | y |
| 两个非负数x y,和一个长度或者百分比z | x | y | z |
旧文推荐: