Flex 布局

2019-03-10

Flex 菜鸟教程

一. Flex布局是什么?

Flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。
任何一个容器都可以指定为Flex布局。

二. 基本概念

采用Flex布局的元素,称为Flex容器(flex container),简称”容器”。它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称”项目”。

三. 容器的属性:

序号 方法 描述
1 flex-direction:
row(占一行排列)
row-reverse(一行反向排列)
column(一列排列)
column-reverse(一列反向排列)
项目的排列方向
2 flex-wrap:
nowrap(不换行)
wrap(换行)
wrap-reverse(换行,第一行在下方)
是否换行
3 flex-flow:
row-reverse wrap
是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap
4 justify-content:
flex-start(左)
flex-end(右)
center(居中)
space-between(左右靠边,中间对齐)
space-around(平均分配空间居中)
定义了项目在主轴(水平)上的对齐方式。
5 align-items:
flex-start(上)
flex-end(下)
center(居中)
baseline(项目的第一行文字的基线对齐)
stretch(如果项目未设置高度或设为auto,将占满整个容器的高度)
定义项目在交叉轴(垂直)上如何对齐。
6 align-content 定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。

四. 项目的属性:

序号 方法 描述
1 flex-grow 定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
2 flex-shrink 定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
3 flex-basis 定义了在分配多余空间之前,项目占据的主轴空间。
4 flex: 1 让所有弹性盒模型对象的子元素都有相同的长度,且忽略它们内部的内容。
是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。
5 order 定义项目的排列顺序。数值越小,排列越靠前,默认为0。
6 align-self 允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。

五. Flex 实例:

小练习

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flex: 1</title>
</head>
<style>
ul,li{
list-style: none;
padding: 0;
margin: 0;
}
ul{
background: green;
display: flex;
}
ul li{
border: 1px solid #fff;
font-size: 30px;
color: #fff;
/* 让所有弹性盒模型对象的子元素都有相同的长度 */
flex: 1;
}

#main{
width: 500px;
height: 300px;
border: 1px solid black;
display: flex;
flex-direction: row;
/* flex-wrap: wrap; */
}
#main div{
/* flex: 1; */
height: 50px;
flex-basis: 110px;
}
#main div:nth-of-type(1){
/* 不能写宽度 */
flex-grow: 1;
}
#main div:nth-of-type(2){
flex-grow: 3;
}
/* #main div:nth-of-type(2){
flex-basis:200px;
} */
.box{
flex-shrink: 1;
}
.box1{
flex-shrink: 2;
}
/* 父元素总和:500px;
子元素总和: 110*5 = 550;
超出总和: 550-500=50
超出的占比例总和: 50*1 + 50*1 + 50*1 + 50*2 + 50*2 = 350;
1/350* 50*50 = 7.14
2/350*50*50 = 14.29
通过收缩因子,每个元素的宽度: 110-7.14, 110-14.29 */
</style>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<hr>
<div id="main">
<div class="box" style="background: coral;">1</div>
<div class="box" style="background: lightblue;">2</div>
<div class="box" style="background: khaki;">3</div>
<div class="box1" style="background: pink;">4</div>
<div class="box1" style="background: lightgrey;">5</div>
</div>
</body>
</html>

六. 补充:

参考

flex是flex-grow,flex-shrink, flex-basis的缩写形式
当 flex 取值为 none,则计算值为 0 0 auto

1
2
3
4
5
6
.item {flex: none;}
.item {
flex-grow: 0;
flex-shrink: 0;
flex-basis: auto;
}

当 flex 取值为 auto,则计算值为 1 1 auto

1
2
3
4
5
6
.item {flex: auto;}
.item {
flex-grow: 1;
flex-shrink: 1;
flex-basis: auto;
}

当 flex 取值为一个非负数字,则该数字为 flex-grow 值,flex-shrink 取 1,flex-basis 取 0%,如下是等同的:

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

flex-grow、flex-shrink、flex-basis三个属性的作用:
(注意:这三个属性都是在子元素上设置的,下面要讲的是父元素,指以flex布局的元素(display:flex))

  1. flex-basis, 默认值为 auto
    意思是<主要成分>,所以和width放在一起时,肯定把width干掉
    使用场景: 重构代码时,有时候会遇到 xxx: xxpx !important 设置时,可以用此属性覆盖。
1
2
3
4
5
6
7
/* 页面展示300px */
.inner{
width:200px;
height:100px;
flex-basis:300px;
background:pink;
}
  1. flex-grow, 默认值为 0
    该属性用来设置当父元素的宽度大于所有子元素的宽度的和时(即父元素会有剩余空间),子元素如何分配父元素的剩余空间。 flex-grow的默认值为0,意思是该元素不索取父元素的剩余空间,如果值大于0,表示索取。值越大,索取的越厉害。

    2.1 举个例子: 父元素宽400px,有两个子元素:A和B。A宽为100px,B宽为200px。 则空余空间为 400-(100+200)= 100px。 如果A,B都不索取剩余空间,则有100px的空余空间。

    2.2
    如果A索取剩余空间:设置 flex-grow: 1,B不索取。则最终A的大小为 自身宽度(100px)+ 剩余空间的宽度(100px)= 200px 。

    2.3
    如果A,B都设索取剩余空间,A设置flex-grow为1,B设置flex-grow为2。
    则最终A的大小为 自身宽度(100px)+ A获得的剩余空间的宽度 100px (1/(1+2))
    则最终B的大小为 自身宽度(200px)+ B获得的剩余空间的宽度 100px (2/(1+2))

    使用场景: todo

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flex: 1</title>
</head>
<style>
.box{
display: flex;
flex-direction: row;
margin:100px auto;
width:400px;
height:200px;
border:1px solid red;

}
.innerA{
flex-basis:100px;
height:100px;
background:pink;
/* flex-grow: 1; */
}
.innerB{
flex-basis:200px;
height:100px;
background:blue;
/* flex-grow: 2; */
}
</style>
<body>
<div class="box">
<div class="innerA"></div>
<div class="innerB"></div>
</div>
</body>
</html>
  1. flex-shrink, 默认值为 1, flex-shrink的值为0时,不缩放.
    该属性用来设置,当父元素的宽度小于所有子元素的宽度的和时(即子元素会超出父元素),子元素如何缩小自己的宽度的。 flex-shrink的默认值为1,当父元素的宽度小于所有子元素的宽度的和时,子元素的宽度会减小。值越大,减小的越厉害。如果值为0,表示不减小。

    3.1
    举个例子: 父元素宽400px,有两个子元素:A和B。A宽为200px,B宽为300px。 则A,B总共超出父元素的宽度为(200+300)- 400 = 100px。 如果A,B都不减小宽度,即都设置flex-shrink为0,则会有100px的宽度超出父元素。

    3.2
    如果A,B都减小宽度,A设置flex-shirk为3,B设置flex-shirk为2。则最终A的大小为 自身宽度(200px)- A减小的宽度(100px * (200px * 3/(200 * 3 + 300 * 2))) = 150px,最终B的大小为 自身宽度(300px)- B减小的宽度(100px * (300px * 2/(200 * 3 + 300 * 2))) = 250px

注意:
如果子容器没有超出父容器,设置 flex-shrink 无效
flex环境默认是不换行的,即使父容器宽度不够也不会,除非设置flex-wrap来换行

使用场景: todo
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flex: 1</title>
</head>
<style>
.box{
display: flex;
flex-direction: row;
margin:100px auto;
width:400px;
height:200px;
border:1px solid red;

}
.innerA{
flex-basis:200px;
height:100px;
background:black;
/* flex-shrink:0; */
flex-shrink: 3;
}
.innerB{
flex-basis:300px;
height:100px;
background:blue;
/* flex-shrink:0; */
flex-shrink: 2;
}
</style>
<body>
<div class="box">
<div class="innerA"></div>
<div class="innerB"></div>
</div>
</body>
</html>

讲解
布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。

2009年,W3C提出了一种新的方案—-Flex布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。(ie10及以上)

Flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。

参考:
ppt 讲解
https://ptteng.github.io/PPT/PPT/css-69-flexbox.html#/1

https://blog.csdn.net/qq_41075132/article/details/82865248
http://zhoon.github.io/css3/2014/08/23/flex.html
https://zhuanlan.zhihu.com/p/47613256