你真的了解flex吗-妈妈再也不用担心我面试被问到flex布局了

711 阅读5分钟

前言

flex布局可以说是现在布局中出现频次最高的佳丽。它可以轻松解决垂直方向对齐,两端布局等css问题。但是你真的足够了解它吗?

通过本篇文章你将会了解到以下内容

  1. flex的基本概念
  2. flex:1代表什么?
  3. 当空间不足的时候,元素大小是怎么分配的

flex的基本概念

其实flex布局不难理解,它主要有两个概念:轴,容器

轴有也分为两个:主轴交叉轴。元素的对齐,和分布都依靠轴来进行。

image.png

默认水平方向是主轴,但是值得注意的是这并不是固定的,我们可以通过flex-direction属性去更改。

容器

容器也分为两个概念,主容器子容器

父容器

image.png

针对父容器的相关属性有六个: flex-wrap, flex-direction, flex-flowjustify-content,align-items,align-content

  • flex-wrap:是控制超出长度时,是否允许父容器换行,默认是no-wrap.
  • flex-direction: 可以更改主轴的方向,默认水平方向。
  • flex-flow:是上面两个属性 flex-directionflex-wrap的组合属性。注意二者的先后顺序,使用的时候要注意顺序。
  • justify-content: 控制子容器在主轴方向的排列。(是主轴方向,并不一定是水平方向)
  • align-items: 控制子容器在交叉轴方向的排列。(是交叉轴方向,并不一定是垂直方向)
  • align-content: 控制多行子容器在交叉轴方向的排列。

子容器

针对子容器的属性正巧也是六个:order,align-self, flex-basis, flex-grow,flex-shrink,flex

  • order: 子容器排列的序号。
  • align-self: 子容器自己在交叉轴的排列方式。
  • flex-basis:子容器在主轴方向上的初始大小。
  • flex-grow:在主轴有剩余空间的时候,子容器的拉伸因子。
  • flex-shrink:在主轴空间不足的时候,子容器的压缩因子。
  • flex: flex-grow/flex-shrink/flex-basis的组合属性

image.png

flex:1究竟代表什么?

有了上面的简单介绍,相信大家都有了初步的了解了。flex:1就是代表了flex-grow/flex-shrink/flex-basis三个属性的组合。那么在flex:1的时候,这三个属性取值分别是多少呢?

image.png

从控制台我们可以看出它代表了:flex-grow:1,flex-shrink:1,flex-basis:0%.那么它就行有什么作用呢?下面我们来详细讲解以下

flex-grow

flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。

image.png

如果设置flex-grow:0则即使有剩余空间,子容器也不会放大,只会保持原来的大小。如果所有项目的flex-grow属性都为1,则它们将等分剩余空间。

flex-shrink

flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。

image.png

flex-basis

flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。
浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。

总结

回头看一下,那么flex:1有什么作用呢?flex-grow:1,flex-shrink:1,flex-basis:0%.那么我们根据上面的理解,它表示空间有剩时可以拉升,空间不足时可以压缩,默认宽度为最小宽度。

最后我们附赠其他缩写表

image.png

拉伸或压缩时元素大小是如何计算的

flex-grow的计算

举个例子

<div class="container">
    <div class="item a">
      <p>A</p>
      <p> width:100</p>
    </div>
    <div class="item b">
      <p>B</p>
      <p> width:150</p>
    </div>
    <div class="item c">
      <p>C</p>
      <p> width:100</p>
    </div>
</div>

// 核心css如下
.container { width: 500px; height: 200px; } 
.a{ width: 100px; } 
.b{ width: 150px; } 
.c{ width: 100px;  }

展示效果如下

image.png

假如我们现在设置A:flex:1 B:flex:2 C:flex:3, 最终我们得到的布局如下:

image.png

以A为例:拉伸后它的宽度为100+(150*1)/6=125px; 100为原始宽度,150为剩余空间,1/6为拉伸因子。 计算公式可以简化为:

自身本来的宽度 + ((自身的flex-grow属性/所有元素的flex-grow之和) * 剩余宽度))

flex-shrink的计算

举个例子

<div class="container">
   <div class="item a">
     <p>A</p>
     <p> width:300</p>
     <p>flex-shrink: 1</p>
   </div>
   <div class="item b">
     <p>B</p>
     <p> width:150</p>
     <p>flex-shrink: 2</p>
   </div>
   <div class="item c">
     <p>C</p>
     <p> width:200</p>
     <p>flex-shrink: 3</p>
   </div>
</div>

css核心代码

.container {
    width: 500px;
}
.a{
   width: 300px;
   flex-shrink: 1;
}
.b{
   width: 150px;
   flex-shrink: 2;
}
.c{
   width: 200px;
   flex-shrink: 3;	
}

image.png

flex-shrink的压缩没有flex-grow那么粗暴直接根据flex-grow的大小比例去压缩。它会根据flex-shrink和本来元素的宽度去综合计算。

上面的例子中,各元素的宽度如下:

宽度总和为650,溢出空间为150 总压缩:300 * 1 + 150 * 2 + 200 * 3 = 1200

A的压缩率:300*1 / 1200 = 0.25 A的压缩值:150 * 0.25 = 37.5 A的实际宽度:300 - 37.5 = 262.5

B的压缩率: 1502 / 1200 = 0.25 B的压缩值: 150 * 0.25 = 37.5 B的实际宽度:150 - 37.5 = 112.5

C的压缩率: 2003 / 1200 = 0.5 B的压缩值: 150 * 0.25 = 75 B的实际宽度:200 - 75 = 125

计算公式如下:

元素宽度 -(宽度*flex-shrink/总压缩)*多出的空间