前言:

flex就是flexible box的缩写,意为弹性布局,任何一个容器都可以指定为flex布局

Webkit内核的浏览器,必须加上-webkit前缀。

1
2
3
4
.box{
display: -webkit-flex; /* Safari */
display: flex;
}

注意:设为 Flex 布局以后,子元素的float、clear和vertical-align属性将失效。

🌀Flex布局与传统布局对比:

传统布局:

  • 兼容性好
  • 布局繁琐
  • 局限(不能在移动端很好的布局)

FLex布局:

  • 操作方便,布局简单,移动端广泛应用
  • PC端浏览器支持较差
  • IE11或更低版本不支持或部分支持

🌀Flex布局原理:

–通过给父元素添加flex属性来控制子元素的位置和排列方式

基本概念

容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end

项目默认沿主轴排列,单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size

容器属性

  1. flex-direction:设置主轴方向,一般默认为x轴
  2. justify-content:设置主轴上的子元素排列方式,一般默认为y轴
  3. flex-wrap:设置子元素是否换行
  4. align-items:设置侧轴上子元素排列方式(单行)
  5. align-content:设置侧轴上子元素排列方式(多行)
  6. align-self:控制子元素本身在交叉轴上的对齐方式
  7. flex-flow:复合属性,同时设置了flex-direction和flex-wrap

flex-direction属性

  • flex-direction属性决定主轴的方向(即项目的排列方向)。
1
2
3
.box {
flex-direction: row | row-reverse | column | column-reverse;
}

属性值:

  • row:默认值,主轴为水平方向,起点在左端。
  • row-reverse:主轴为水平方向,起点在右端。
  • column:主轴为垂直方向,起点在上沿。
  • column-reverse:主轴为垂直方向,起点在下沿
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<body>
<div class="flex">
<div class="box">第一个盒子1</div>
<div class="box box2">第二个盒子2</div>
<div class="box box3">第三个盒子3</div>
<div class="box box4">第四个盒子4</div>
<div class="box box5">第五个盒子5</div>
</div>
</body>
</html>

<style>
.flex{
display: flex;
flex-direction: row-reverse;
background-color: lime;
}

.box{
width: 100px;
height: 100px;
background-color: rgb(199, 220, 220);
}
.box2{
background-color: chartreuse;
}
.box3{
background-color: gray;
}
.box3{
background-color: red;
}
.box4{
background-color: cadetblue;
}
.box5{
background-color: darkturquoise;
}
</style>

justify-content属性

  • justify-content 是用于控制项目在主轴上的对齐方式。

  • 常用属性有以下六个

1
2
3
.box {
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
}

属性值:

  • flex-start:默认值,子盒子在主轴方向上排列,一般是在x轴水平方向,从左到右。
  • flex-end:子盒子在主轴方向上反向排列,一般是在x轴水平方向,从右到左边。
  • center:子盒子在主轴方向上居中。
  • space-between:子盒子在主轴方向上,两端对齐,然后项目中间间隔是相等的。
  • space-around:在主轴方向上,在左右两侧会留下边距。
  • space-evenly:均匀排列每个元素,每个元素之间的间隔相等

space-around、space-evenly和space-between的区别

flex-wrap属性

  • flex-wrap: 控制项目(子元素)是否换行

它可能取三个值:

  • nowrap:(默认值)不换行;
  • wrap:换行,第一行在上方;
  • wrap-reverse:换行,第一行在下方。

注意:默认情况下是不换行的,如果父元素装不下会缩小所有子元素的宽度,使子元素挤在一起。

如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<body>
<div class="flex">
<div class="box">第一个盒子1</div>
<div class="box box2">第二个盒子2</div>
<div class="box box3">第三个盒子3</div>
<div class="box box4">第四个盒子4</div>
<div class="box box5">第五个盒子5</div>
</div>
</body>
</html>
<style>
.flex{
display: flex;
background-color: lime;
width: 300px;
}

.box{
width: 100px;
height: 100px;
background-color: rgb(199, 220, 220);
}
</style>
  • 这里我父盒子长度设为300px,每个子盒子长度设为100px,此时不设置flex-wrap:wrap,会发生什么情况呢?
  • 没错,不会换行,子盒子的宽度100px失效了会自适应父盒子的宽度,主要是根据原本的宽度大小来进行等比缩放
  • 如图

  • 那么如果设置了flex-wrap:wrap,超出的部分就会进行分行
  • 如图

align-items属性

  • align-items 是控制项目在交叉轴上的对齐方式,一般是垂直方向y轴上面的。
  • 有常用的五个属性
1
2
3
.box {
align-items: stretch | flex-start | flex-end | center | baseline;
}
  • stretch:默认值,如果项目没有设置固定高度,则会被拉伸填充满交叉轴方向剩余的空间。
  • flex-start:项目在沿交叉轴起始线位置对齐。
  • flex-end:项目沿交叉轴终点线位置对齐。
  • center:项目在交叉轴方向居中对齐。
  • baseline:项目在交叉轴方向沿项目中第一行文字的基线对齐。

  1. stretch 是“拉伸,拉长”的意思,所以项目会被拉伸
  2. start、end、center 分别的“起始”、“终点”、“中间”的意思,所以项目分别是起始位置、终端位置、居中对齐。
  3. baseline 是“基线、底线”的意思,这里是沿文字的基线对齐的意思。

align-content属性

  • align-content 控制多行项目(多根主轴线)对齐方式。类似 justify-content ,只不过,align-content 是控制行与行之间的空间分配,justify-content 是控制子盒子与子盒子之间的空间分配。
  • 有七个常用的属性
1
2
3
.box {
align-content: stretch | flex-start | flex-end | center | space-between | space-around | space-evenly;
}
  • 除了stretch属性外,其他的属性功能和性质基本和justify-content那里的属性一样
  • stretch:默认值,交叉轴方向剩余的空间平均分配到每一行,并且行的高度会拉伸,填满整行的空间

align-self属性

  • align-self 控制子盒子本身在交叉轴上的对齐方式。优先级高于 align-itemsalign-items 是容器统一控制容器里的每个子盒子的对齐方式,align-self 则是子盒子控制子盒子本身的对齐方式。
1
2
3
.item-box {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
  • 默认值:align-self: auto; ,继承容器设置的 align-items 的值。也就是默认是由容器设置 align-items 统一控制项目在交叉轴上的对齐方式。
  • 除了比 align-items 多一个 auto 选项外,其他选项与 align-items 一致。
1
2
3
4
5
6
7
.container {
dispaly: flex;
align-items: flex-start; // 容器控制所有项目顶部对齐排列
}
.item.four {
align-self: flex-end; // 第四个项目控制底部对齐
}

flow-grow属性

  • flex-grow 用于控制子盒子在主轴方向上拉伸放大占剩余空间(如果有的话)的比例。
  • grow 的意思是“扩大,使生长”,所以就是让项目放大的意思。
1
2
3
.item-box {
flex-grow: <number>;
}
  • 默认值:0,不放大。

例子中,容器宽设为 300px,项目宽设为 50px。项目总宽 150px,剩余空间宽 150px

flex-grow 都设置为 1 的时候,项目拉伸成 100px,剩余空间被按 1:1:1 分配,每个项目各占了 1/3。

flex-grow 分别设为 33、66、66 的时候,项目分别被拉伸成 87.5px、125px、87.5px,剩余空间被按 1:2:1 分配,项目分别占了剩余空间的 1/4、1/2、1/4。

可以看到,放大的比例跟数值的大小无关,跟数值的比例有关。

flow-shrink属性

  • flex-shrink 用于控制项目在主轴方向上缩小的程度。数值越大,收缩越多
1
2
3
.item-box {
flex-shrink: <number>;
}
  • 默认是 flex-shrink: 1 ,同等比例收缩。

例子中,容器宽为 400px,项目宽为100px。因为项目超过了容器空间,所以自动被缩小了。默认 flex-shrink 是 1,所有项目同等比例缩小成 80px。

右上,设置 flex-shrink,全部设置为 0,项目保存原来设置的宽度 100px,不缩小,所以溢出容器空间。

右中,设置 flex-shrink 分别为 6、6、6、默认、默认,项目宽变成 70px、70px、70px、95px、95px,超出的 100px 分成 20 份,按比例缩小。

右上,设置 flex-shrink 分别为 999、默认、默认、默认、默认,项目宽变成 16px、96px、96px、96px、96px,可以看到这里就不按比例缩小的了。

flex-basis属性

  • flex-basis 用于初始化每个项目占据主轴空间的尺寸(main size)
1
2
3
.item-box {
flex-basis: <length> | auto;
}
  • 默认值:flex-basis: auto , 自动检测尺寸,如果项目有设置尺寸,则取项目设置的值,否则根据项目内容计算出尺寸。

flex 项目的属性:flex

  • flex 是上面三个合并的简写。
1
2
3
.item {
flex: <flex-grow> [<flex-shrink>] [<flex-basis>];
}
  • 默认值:flex: 0 1 auto; 后两个参数为可选参数。
  • flex: auto:等同于 flex: 1 1 auto。可以拉伸,可以缩小,自动计算项目尺寸,一般情况下会自动拉伸填充满整个容器。
  • flex: none: 等同于 flex: 0 0 auto。不能拉伸,不能缩小,直接使用获取到项目的 flex-basis 尺寸。
  • flex: <positive-number>:等同于 flex: <positive-number> 1 0 。positive-number 为正数,例如 flex: 1 等同于 flex: 1 1 0

flex 项目的属性:order

  • order 用于控制项目在主轴上的排列顺序。
1
2
3
.item-box {
order: <number>;
}
  • 默认值: order: 0; ,参数值正负数都可以,全部项目按主轴方向依次排列。设置后,按数值大小,从小到大排列。