title: Flex布局

date: 2021-05-09 21:40:26.907
updated: 2021-05-14 22:59:39.249
url: /?p=158
categories: 前端
tags: 前端

简介

传统的网页布局方案,一般是使用float+position+display的方案。其缺点也很明显,代码逻辑紊乱。

在2009年,W3c提出了一种新的方案——Flex布局。其逻辑清晰(直觉友好),简单,完整,对响应式布局友好。

对于Flex局部的兼容性,只要不适配IE浏览器,可以放心在其它浏览器使用。

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

指定Flex布局

任何一个容器都可以指定为Flex容器:

块元素指定为Flex容器

1
2
3
.box{
diaplay:flex;
}

行内元素指定为Flex容器

1
2
3
.box{
display:inline-flex;
}

Webkit 内核

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

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

注意,设为 Flex 布局以后,子元素的floatclearvertical-align属性将失效。

基本概念

指定了Flex布局的我们一般称它为“Flex容器”。

Flex容器内的子元素我们称它为“项(item)”

注意Flex容器中的主轴(main axis)和交叉轴(cross axis),main startmain end分别指的是主轴开头和结尾,cross startcross end指的是交叉轴的开头和结尾。沿着主轴方向的宽度称为main size,沿着交叉轴方向的宽度称为cross size

Flex容器的属性

属性值 属性名 作用
flex-direction row 、row-reverse 、column 、column-reverse 指定主轴的方向。row为水平方向,其以main start为开头,column为垂直方向,以main start为开头。row-start和column-reverse同理。
flex-wrap nowrap、wrap、wrap-reverse 设定是否换行,默认不换行。nowrap不换行,wrap换行,wrap-reverse表示第一行以main start开头。
flex-flow flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
justify-content flex-start、flex-end、center、space-between、space-around 主轴的对齐方式
align-items flex-start、flex-end、center、baseline、stretch; 交叉轴的对齐方式
align-content flex-start、flex-end、center、space-between、space-around、stretch 多行内容的交叉轴的对齐方式。flex-start:与交叉轴的起点对齐。 flex-end:与交叉轴的终点对齐。 center:与交叉轴的中点对齐。 space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。 space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。 stretch(默认值):轴线占满整个交叉轴。

Flex容器子元素(item)的属性

属性名 属性值 内容
order 数值越小,排列越靠前,默认为0。
flex-grow 子元素伸长比例,默认为0,即如果存在剩余空间,也不放大。
flex-shrink 子元素缩小比例,默认为1,即如果空间不足,该项目将缩小。
flex-basis flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
flex flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。
align-self auto、flex-start、flex-end、center、baseline、stretch; align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。

如果有四个子元素为100ox,但是父布局只有300,那么会怎么样?

既然100px没有,那么我们不设置子元素的宽度会怎么样?

剩余空间调整

justify-content

属性值 作用
flex-start 默认值,沿着主轴方向,在开头聚集。
flex-end 主轴方向,在末尾聚集。
center 主轴方向,中间聚集。
space-between 主轴方向,平均分配,间隔(空格)在两者之间,两边不留间隔
space-around 主轴方向,平均分配,间隔(空格)环绕每个元素,两边留间隔

交叉轴的对齐方式

align-items

属性值 作用
flex-start 默认值,沿着主轴方向,在开头聚集。
flex-end 主轴方向,在末尾聚集。
center 主轴方向,中间聚集。

子元素设置伸缩比例

flex-basis 设置后,width失效
flex-grow 按照剩余部分的空间按照比例分配。通过basis计算
flex-shrink 空间不足时,按照比例缩放,如果是0,表示不缩放。通过basis计算
flex 上面三者的缩写

flex特殊写法

属性 作用
flex:auto; flex:1 1 auto;
flex:none; flex:0 0 auto;
flex:0%;/ flex:100px; flex:1 1 0%; / flex:1 1 100px;
flex:1; flex:1 1 0%;

输入框布局

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}

#mydiv{
width: 250px;
display: flex;
border: 1px solid #dcdcdc;
}

#mydiv label{
flex: 1;
background-color: #f5f5f5;
text-align: center;
}

#mydiv label:nth-child(3){
flex: 0 0 25px;
}


#mydiv input{
border: none;
outline: none;
}



</style>
</head>
<body>
<div id="mydiv">
<label>姓名</label>
<input type="text">
<label>GO</label>
</div>
</body>
</html>

长表达布局

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}

#form div{
display: flex;
align-items: flex-start;
flex: 0 0 30px;
}

#form div label{
flex: 0 0 100px;
text-align: end;
}


#form{
display: flex;
flex-direction: column;
justify-content: center;
}

</style>
</head>
<body>
<form>
<div id="form">
<div>
<label>姓名:</label>
<input type="text">
</div>
<div>
<label>请输入密码:</label>
<input type="text">
</div>
</div>
</form>
</body>
</html>

参考文献

  1. 阮一峰——Flex布局语法:https://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
  2. Flex布局示例:http://static.vgee.cn/static/index.html