什么是flex布局

flex布局又称为弹性盒子模型,它有自己的一套属性,效率高,学习成本低,兼容性强!

弹性盒子模型实现 HTML 页面布局是与方向无关的。不类似于块级布局侧重垂直方向,内联布局侧重水平方向。

弹性盒子模型主要适用于 HTML 页面的组件以及小规模的布局,而并不适用于大规模的布局,否则会影响 HTML 页面性能。

名词定义

img

  • 伸缩容器(flex container):包裹伸缩项目的父元素。
  • 伸缩项目(flex item):伸缩容器的每个子元素。
  • 轴(axis):每个弹性盒子模型拥有两个轴。
    • 主轴(main axis):伸缩项目沿其一次排列的轴被称为主轴。
    • 侧轴(cross axis):垂直于主轴的轴被称为侧轴。
  • 方向(direction):伸缩容器的主轴由主轴起点和主轴终点,侧轴由侧轴起点和侧轴终点描述伸缩项目排列的方向。
  • 尺寸(dimension):根据伸缩容器的主轴和侧轴,伸缩项目的宽度和高度。
    • 对应主轴的称为主轴尺寸。
    • 对应侧轴的称为侧轴尺寸。

定义弹性盒子

弹性盒子是css3新增的属性,因此弹性盒子模型及其属性存在浏览器兼容问题。具体可查看Can I Use

1
2
3
4
div {
display : flex;
display : inline-flex;
}
  • flex:设置指定元素为块级元素的弹性盒子模型。
  • inline-flex:设置指定元素为行内块级元素的弹性盒子模型。

浏览器兼容前缀

1
2
3
4
5
6
div{
display : -webkit-flex;
display: -ms-flex;
display: -moz-flex;
display: -o-flex;
}

会将容器内的元素按照水平方向进行排列。容器内的元素类似于浮动水平排列在一起

image-20210125153111540

将容器内的元素视为块级元素,按行排列在一起。

image-20210125153621860

容器属性

用于测试的HTML结构。

1
2
3
4
5
6
7
<div class="container">
<div style="background-color: lightgray">盒子1</div>
<div style="background-color: lightgreen">盒子2</div>
<div style="background-color: lightpink">盒子3</div>
<div style="background-color: lightsalmon">盒子4</div>
<div style="background-color: lightskyblue">盒子5</div>
</div>

本文所涉及的属性为常用属性及其取值,更多属性及取值请参考MDN

以下属性作用域弹性盒子的容器。

创建主轴方向

元素基础样式

1
2
3
4
5
6
7
8
9
.container {
width: 900px;
border: 3px solid black;
display: flex;
}
.container div {
width: 120px;
height: 300px;
}

flex-direction 属性用于创建主轴的方向。

容器内子元素的排列方向

image-20210125184805938

row:设置主轴是水平方向。

image-20210125154908007

1
2
3
.container {
flex-direction: row;
}

row-reverse:与 row 的排列方向相反。

image-20210125154954030

1
2
3
.container {
flex-direction: row-reverse;
}

column:设置主轴是垂直方向。

image-20210125155251253

1
2
3
.container {
flex-direction: column;
}

column-reverse:与 column 的排列方向相反。

image-20210125155324411

1
2
3
.container {
flex-direction: column-reverse;
}

设置沿主轴线的对齐方式

CSS justify-content 属性适用于伸缩容器元素,用于设置伸缩项目沿着主轴线的对齐方式。关于此属性更多取值参考MDN

css基础样式

1
2
3
4
5
6
7
8
9
.container {
width: 900px;
border: 3px solid black;
display: flex;
}
.container div {
width: 120px;
height: 300px;
}

image-20210125184836199

center:伸缩项目向第一行的中间位置对齐。

image-20210125160041613

1
2
3
.container {
justify-content: center;
}

flex-start:伸缩项目向第一行的开始位置对齐。

image-20210125160455842

1
2
3
.container {
justify-content: flex-start;
}

flex-end:伸缩项目向第一行的结束位置对齐。

image-20210125160618374

1
2
3
.container {
justify-content: flex-end;
}

space-between:伸缩项目会平均分布在一行中。

image-20210125160658914

1
2
3
.container {
justify-content: space-between;
}
小技巧

当只有两个元素时会导致元素左右两端对齐,如图:

image-20210129162910972

可以通过对容器进行设置伪类样式将其排列。

1
2
3
4
5
.container::after {
content: '';
/* 设置成一个子元素的宽度 */
width: 200px;
}

image-20210129163012081

space-around:伸缩项目会平均分布在一行中,两端保留一半的空间。

image-20210125160743719

1
2
3
.container {
justify-content: space-around;
}

设置沿侧轴线的对齐方式

CSS align-items 属性适用于伸缩容器元素,用于设置伸缩项目所在行沿着侧轴线的对齐方式。

基础CSS样式

1
2
3
4
5
6
7
8
9
10
11
12
.container {
width: 900px;
height: 300px;
border: 3px solid black;
display: flex;
/* 主轴对齐方式 */
justify-content: space-between;
}
.container div {
width: 120px;
height: 150px;
}

image-20210125184854429

stretch:默认值,伸缩项目拉伸填充整个伸缩容器。

image-20210125162146943

1
2
3
4
.container {
/* 侧轴对齐方式 */
align-items: stretch;
}

center:伸缩项目向侧轴的中间位置对齐。

image-20210125162237276

1
2
3
4
.container {
/* 侧轴对齐方式 */
align-items: center;
}

flex-start:伸缩项目向侧轴的起点位置对齐。

image-20210125162146943

1
2
3
4
.container {
/* 侧轴对齐方式 */
align-items: flex-start;
}

flex-end:伸缩项目向侧轴的终点位置对齐。

image-20210125162455304

1
2
3
4
.container {
/* 侧轴对齐方式 */
align-items: flex-end;
}

baseline:伸缩项目根据伸缩项目的基线对齐(第一行文字)。

image-20210125191144903

1
2
3
4
.container {
/* 侧轴对齐方式 */
align-items: baseline;
}

设置单/多行显示

CSS flex-wrap 属性适用于伸缩容器元素,用于设置伸缩容器的子元素是单行显示还是多行显示。

基础css样式

1
2
3
4
5
6
7
8
9
10
11
12
.container {
width: 900px;
height: 300px;
border: 3px solid black;
display: flex;
/* 主轴对齐方式 */
justify-content: space-between;
}
.container div {
width: 120px;
height: 150px;
}

image-20210125184821421

nowrap:设置伸缩项目单行显示。这种方式可能导致溢出伸缩容器。

image-20210125163058707

可见,容器宽度900px,容器内一共9个子元素,每个120px,他们紧紧的排列在一起。

1
2
3
.container {
flex-wrap: nowrap;
}

wrap:设置伸缩项目多行显示。

image-20210125163225279

当多行显示时,第一行放不下的元素会被放到下一行(第二行),因为设置了主轴对齐方式为space-between,所以多出来的两个元素分别到了两端。

1
2
3
.container {
flex-wrap: wrap;
}

wrap-reverse:与 wrap 相反。

image-20210125163428589

当多行显示时,第一行放不下的元素会被放到上一行(第二行),因为设置了主轴对齐方式为space-between,所以多出来的两个元素分别到了两端。

1
2
3
.container {
flex-wrap: wrap-reverse;
}

设置伸缩行的对齐方式

CSS align-content 属性适用于伸缩容器元素,用于设置浏览器如何沿着弹性盒子布局的纵轴和网格布局的主轴在内容项之间和周围分配空间。**该属性对单行弹性盒子模型无效。(即:带有 flex-wrap: nowrap)。**更多参考MDN

基础CSS样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.container {
width: 900px;
height: 600px;
border: 3px solid black;
/* 将当前元素设置为弹性盒子模型的伸缩容器 */
display: flex;
/* justify-content属性表示项目在主轴的对其方式 */
justify-content: space-between;
/* 设置伸缩项目是单行显示还是多行显示 */
flex-wrap: wrap;
}
.container div {
width: 120px;
height: 150px;
}

image-20210125184919489

stretch:默认值,各行将会伸展以占用额外的空间。

image-20210125165443121

1
2
3
4
.container {
/* align-content属性设置伸缩项目所在行的对齐方式 */
align-content: stretch;
}

center:各行向伸缩容器的中间位置对齐。

image-20210125165530820

1
2
3
4
.container {
/* align-content属性设置伸缩项目所在行的对齐方式 */
align-content: center;
}

flex-start:各行向伸缩容器的起点位置对齐。

image-20210125165550793

1
2
3
4
.container {
/* align-content属性设置伸缩项目所在行的对齐方式 */
align-content: flex-start;
}

flex-end:各行向伸缩容器的终点位置对齐。

image-20210125165606310

1
2
3
4
.container {
/* align-content属性设置伸缩项目所在行的对齐方式 */
align-content: flex-end;
}

space-between:各行会平均分布在一行中。第一项与起始点齐平,最后一项与终止点齐平。

image-20210125165641772

1
2
3
4
.container {
/* align-content属性设置伸缩项目所在行的对齐方式 */
align-content: space-between;
}

space-around:各行会平均分布在一行中,两端保留一半的空间。

image-20210125165729566

1
2
3
4
.container {
/* align-content属性设置伸缩项目所在行的对齐方式 */
align-content: space-around;
}

flex-flow

CSS flex-flow 属性适用于伸缩容器元素,该属性是 flex-directionflex-wrap 的简写。

其语法:flex-flow: <'flex-direction'> || <'flex-wrap'>,示例:flex-flow: row wrap

项目属性

flex 属性

flex属性是的属性简称。用于定义剩余空间的分配。更多参考MDN

  • flex-grow

    属性定义项目的放大比例(剩余空间按比例分配)。默认为0,即如果存在剩余空间,也不放大。

    其属性的取值为数字。

    image-20210125185100165

  • flex-shrink

    属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。

    image-20210125185119475

    如果所有项目的flex-shrink属性都为1(默认),当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。负值对该属性无效。

  • flex-basis

    属性定义了在分配多余空间之前,项目占据的主轴空间(main size) 和width有一定的关系,大部分情况和width表现一致,如果两者同时使用flex-basis优先级会高一些

    使用注意
    1. 单独使用width,正常使用
    2. 如果单独使用flex-basis,超过会自动变大,不会限制,相当于flex-basis是最小宽度。
    3. 如果同时使用,实际宽度为限制flex-basiswidth两者的最大者,并且会限制,内容超出直接溢出(不使用break-all)
    4. 如果有max-widthmin-widthflex-basis受到这两个属性的限制,flex-basis = max-widthflex-basis = max-width

    如果flex-basis没有设置,flex-basis = width;如果width也没有设置,flex-basis = content的宽度

三个值的取值以及含义参考博文:css弹性盒子

  • 一个无单位数(): 它会被当作flex:<number> 1 0; <flex-shrink>的值被假定为1,然后<flex-basis> 的值被假定为0。

  • 一个有效的宽度(width)值: 它会被当作的值。

  • 关键字none,auto或initial.

第一个值必须为一个无单位数,并且它会被当作 <flex-grow> 的值。第二个值必须为以下之一:

  • 一个无单位数:它会被当作 <flex-shrink> 的值。
  • 一个有效的宽度值: 它会被当作 <flex-basis> 的值。
  • 第一个值必须为一个无单位数,并且它会被当作 <flex-grow> 的值。

  • 第二个值必须为一个无单位数,并且它会被当作 <flex-shrink> 的值。

  • 第三个值必须为一个有效的宽度值, 并且它会被当作 <flex-basis> 的值。

平均分配,中间大左右小

image-20210125175448393

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<style>
.container {
width: 900px;
height: 600px;
border: 3px solid black;
/* 将当前元素设置为弹性盒子模型的伸缩容器 */
display: flex;
}
.container div {
height: 150px;
flex: 1;
}
.container div:nth-child(2) {
flex: 2;
}
</style>
<body>
<div class="container">
<div style="background-color: lightgray">盒子1</div>
<div style="background-color: lightgreen">盒子2</div>
<div style="background-color: lightpink">盒子3</div>
</div>
</body>

将每个div配1等份,而第二个div分配2等份即可。

设置自身元素在侧轴的对齐方式

CSS align-self 属性适用于伸缩容器元素,用于设置伸缩项目自身元素在侧轴的对齐方式。实际上效果与容器属性align-content较为类似

基础样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.container {
width: 900px;
height: 600px;
border: 3px solid black;
/* 将当前元素设置为弹性盒子模型的伸缩容器 */
display: flex;
/* justify-content属性表示项目在主轴的对其方式 */
justify-content: space-between;
/* 设置伸缩项目是单行显示还是多行显示 */
flex-wrap: wrap;
}
.container div {
width: 120px;
height: 150px;
align-self: center;
}

stretch:默认值,伸缩项目拉伸填充整个伸缩容器。

1
2
3
.container div {
align-self: stretch;
}

image-20210125165443121

center:伸缩项目向侧轴的中间位置对齐。

image-20210125165530820

1
2
3
.container div {
align-self: center;
}

flex-start:伸缩项目向侧轴的起点位置对齐。

image-20210125165550793

1
2
3
.container div {
align-self: flex-start;
}

flex-end:伸缩项目向侧轴的终点位置对齐。

image-20210125165606310

1
2
3
.container div {
align-self: flex-end;
}

baseline:伸缩项目根据伸缩项目的基线对齐。

image-20210125191732822

1
2
3
4
5
6
7
.container div {
align-self: baseline;
}
.container span {
height: 80px;
line-height: 80px;
}

设置布局时的顺序

CSS order 属性适用于伸缩项目,用于设置伸缩项目在布局时的顺序。默认为0,值越大越靠后。

image-20210125183116414

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
<style>
.container {
width: 900px;
height: 600px;
border: 3px solid black;
/* 将当前元素设置为弹性盒子模型的伸缩容器 */
display: flex;
/* justify-content属性表示项目在主轴的对其方式 */
justify-content: space-between;
/* 设置伸缩项目是单行显示还是多行显示 */
flex-wrap: wrap;
}
.container div {
width: 120px;
height: 150px;
}
.container div:nth-child(1) {
order: 2;
}
.container div:nth-child(2) {
order: 3;
}
.container div:nth-child(3) {
order: 1;
}
</style>
<div class="container">
<div style="background-color: lightgray">盒子1 - order:2</div>
<div style="background-color: lightgreen">盒子2 - order:3</div>
<div style="background-color: lightpink">盒子3 - order:1</div>
</div>