终于搞懂了 flex:1是怎么工作的了!

736 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

今天在写flex布局的时候,在思考 CSS 中的 flex属性到底是如何工作的?

flex是 flex-growflex-shrinkflex-basis的简写,开发中最常见的写法是flex:1,它表示 flex 项目扩展并填充可用空间。

flex-grow

flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。flex-grow的值只接受一个整数。

 <style>
    .wrapper {
      display: flex;
      flex-wrap: wrap;
    }
    .box-1 {
      /* flex-grow: 1; */
      height: 40px;
    }
    .item-1 {
      background-color: antiquewhite;
    }
    .item-2 {
      background-color: aqua;
    }
    .item-3 {
      background-color: burlywood;
    }
  </style>

  <body>
    <div class="wrapper">
        
      <div class="box-1 item-1">22</div>
        
      <div class="box-1 item-2">2222222222</div>
        
      <div class="box-1 item-3">222222222222222222222</div>
    </div>
  </body>

flex-grow会影响宽度或高度,具体取决于flex-direction属性。对于刚刚的例子,默认的flex-direction的值都是row。在不使用flex-grow的情况下,flex项目宽度将默认为初始宽度,但是使用了 flex-grow: 1;的时候,flex项目会平均剩余可用的空间。

不使用 flex-grow: 1;的结果:

image.png

使用 flex-grow: 1;的结果:

image.png

在控制台查看宽度的时候发现其实三个div的宽度是不一样的,那到底是怎么计算的呢?可以参考这个公式:

项目宽度 = (( flex-grow / flex-grow 总个数) * 可用空间)+ 初始项目宽度

疑问一:flex布局中的div的flex-grow可以不一样吗?

这时候可以试试把div的flex-grow改为2试试:

改之前: image.png 改之后: image.png

疑问二:flex-grow可以是0吗?

可以,因为flex-grow属性可以接受整数值,是可以使用0的:

image.png

这样设置还能防止这个div占用剩余空间,保持它初始宽度。

疑问三:flex项目会平均剩余可用的空间是指平均分配空间吗?

不是的,常见的误解是使用了flex-grow会让每个div的宽度相等,这是错误的理解,flex-grow的作用是分配可用空间,在公式中就能看出来每个div的宽度是以初始宽度计算的为基础的,如果想让每个div宽度相等,可以使用flex-basis

flex-shrink

flex-shrink属性定义了项目的缩小比例,默认为1,意思就是空间不足的时候,div会缩小。

  • 所有div宽度的总和小于外层宽度的时候
  • 窗口宽度等于小于该div

解释:如图所示,在窗口宽度大于1000的时候,div宽度为1000,在窗口宽度小于1000的时候,div的宽度等于窗口的宽度

image.png

image.png

image.png

flex-basis

flex-basis属性定义了在分配空间之前,div占据的主轴空间,浏览器会根据这个属性,计算主轴是否有多余的空间,默认值为auto,就是div本来的大小。

flex-basis可以设为跟widthheight属性一样的值(比如 1000px,默认值为 auto),则项目将占据固定空间。

举个栗子:在这里把div设置为flex-basis: 50%;,将flex-grow重置为 0,以防止宽度超过50%

 .item-2 {
      /* width: 1000px; */
      flex-shrink: 0;
      flex-grow: 0;
      flex-basis: 50%;
      background-color: aqua;
    }

image.png

再举个栗子:将 flex-basis 设置为 100%,该div单独占一行,其他div将换行。

 .item-2 {
      /* width: 1000px; */
      flex-shrink: 0;
      flex-grow: 0;
      flex-basis: 100%;
      background-color: aqua;
    }

image.png

总结

flex的相对大小

div的大小取决于内容的大小

.item {
  flex: auto; // flex-grow:0; flex-shrink:1; flex-basis:auto;
}

flex的绝对大小

div的大小保持一致

.item {
  flex: 1; // flex-grow:0; flex-shrink:1; flex-basis:0%;
}

搞懂了flex属性的内涵,还是建议直接使用简写:

建议开发者使用 flex 简写来控制灵活性,而不是直接使用它的普通属性,因为简写的可以正确地重置任何未指定的组件以适应常见情景。