理解flex布局的flex-grow、flex-shrink、flex-basis

1,635 阅读4分钟

当前,大家最常用的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占领值实际值
A100px0(默认)0 / ( 0 + 1 + 2) * 300 = 0px0 + 100 = 100px
B100px11 / ( 0 + 1 + 2) * 300 = 100px100 + 100 = 200px
C00px22 / ( 0 + 1 + 2) * 300 = 200px200 + 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总压缩权重压缩率宽度
A200px1(默认)1200 + 1200 + 2*200 = 8001 * 200 / 800 = 0.25200 - 0.25 * 200 = 150px
B200px11 * 200 / 800 = 0.25200 - 0.25 * 200 = 150px
C200px22 * 200 / 800 = 0.5200 - 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
非负数字xx10%
0010%
长度或百分比x11x
两个非负数x yxy0%
一个非负数x和一个长度或者百分比yx1y
两个非负数x y,和一个长度或者百分比zxyz

旧文推荐

  1. 微信小程序又双叒叕改重要接口了!
  2. 微信标准版交易组件使用入门
  3. 如何利用小程序广告赚钱?

PS: 欢迎关注我的商城项目, Github, Gitee