1.什么是Flex布局
传统的布局方案都是基于盒装模型,依赖于display属性+position属性+float属性来实现。他对于一些特殊布局来说就很难实现,例如:垂直居中布局
2009年,W3C提出了一种新的方案,flex布局,可以简便,完整,响应地实现各种页面布局。目前,它已经得到了所有浏览器的支持。
Flex布局又叫弹性布局,用来为盒装模型提最大的灵活性,任何一个盒子都能指定为Flex布局
块元素:
.block {
display: flex;
}
行内元素:
.inline {
display: inline-flex;
}
当设为Flex布局以后,子元素的float,clear和vertical-align属性将失效
2.基本概念
当容器采用flex布局后,称为flex容器,简称容器。它的所有的子元素将会自动成为容器的成员,称为flex项目,简称项目
从上面图中可以看出,容器存在两根轴:主轴(main axis)和垂直的交叉轴(cross axis)
主轴开始的地点叫main start,主轴结束的地点叫main end,从左到右
交叉轴开始的位置叫cross start,交叉轴结束的位置叫cross end,从上到下
项目默认沿着主轴排列
3.容器的基本属性
容器主要有以下六个属性
- flex-direction
- flex-wrap
- flex-flow
- justify-content
- align-item
- align-content
3.1 flex-direction
flex-direction主要用来决定主轴的排列方向,它有四个值可以选择,row,row-reverse,clumn,clumn-reverse
- row(默认):主轴为水平方向,起点为左边
- row-reverse:主轴为水平方向,起点为右边
- clumn:主轴为垂直方向,起点在上边
- clumn-reverse:主轴为垂直方向,起点在下边
.box {
flex-direction: row | row-reverse | column | column-reverse;
}
3.2 flex-wrap
默认情况下,flex布局中所有的元素都排在一条轴线上,当一条轴线放不下时,会挤压子元素,改变子元素的宽度。我们也可以通过设置flex-wrap属性来使当轴线排布下时,子元素可以换行显示。它又三个值可以选择:nowrap,wrap,wrap-reverse
- nowrap(默认):不换行
- wrap:换行,第一行在上方
- wrap-reverse:换行,第一行在下方
.box {
flex-wrap: nowrap ] wrap ] wrap-reverse
}
nowrap
wrap
wrap-reverse
3.3 flex-flow
flex-flow为flex-direction和flex-wrap的简写形式,默认值为row和nowrap
.box {
flex-flow: <flex-direction> || <flex-wrap>;
}
3.4 justify-content
justify-content主要用来修改项目在主轴上的对齐方式,主要有以下的属性值
- center:居中对齐
- left:伸缩元素一个挨一个在对齐容器的左边缘
- right:伸缩元素一个挨一个在对齐容器的右边缘
- start:从主轴的开始排列,每行第一个元素与行首对齐,后面所有元素与前一个元素对齐
- end:从主轴的行尾排列,每行的最后一个元素与行尾对齐,前面所有元素与后一个对齐
- flex-start(默认):从主轴的开始排列。每行的第一个弹性元素与行首对齐,后面所有的弹性元素都与前一个对齐
- flex-end:从主轴的行尾排列。每行的最后一个弹性元素与行尾对齐,所有弹性元素与前一个对齐
- space-around:弹性元素均匀分布。相邻元素间距离相等,每行第一个元素到行首的距离与每行最后一个元素到行尾的距离等于相邻元素间距离的一半
- space-between:弹性元素均匀分布。相邻元素间距离相等,每行的第一个元素到行首的距离与每行的最后一个元素到行尾的距离为0
- space-evenly:弹性元素均匀分布。相邻元素间距离相等,每行第一个元素到行首的距离与每行最后一个元素到行尾的距离为相邻元素间的距离
样式代码:
<div class="box-wrap">
<div class="box first">第一个盒子</div>
<div class="box">第二个盒子</div>
<div class="box">第三个盒子</div>
<div class="box">第四个盒子</div>
<div class="box last">第五个盒子</div>
</div>
.box-wrap {
width: 1100px;
height: 600px;
background-color: blue;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: left;
}
.box {
width: 300px;
height: 68px;
font-size: 20px;
background-color: red;
border: 1px solid white;
}
.first {
height: 30px;
font-size: 12px;
}
.last {
height: 100px;
font-size: 30px;
}
center:
row下的
column下的
left:
row下的
colum下的
right:
row下的
column下的
start:
row下的
column下的
end:
row下的
column下的
flex-start:
row下的
column下的
flex-end:
row下的
column下的
space-around:
row下的
column下的
space-between
row下的
column下的
space-evenly:
row下的
column下的
3.5 align-items
align-items用来设置元素在交叉轴上的对齐方式,它可以有以下的取值
- normal:只有在绝对布局中,对于被替代的绝对定位盒子,效果和start一样,其余情况和strech一样
- flex-start:元素交叉轴起点对齐
- flex-end:元素交叉轴终点对齐
- start:元素交叉轴起点对齐
- end:元素交叉轴终点对齐
- center:元素在交叉轴居中。如果元素在交叉轴的高度大于容器的高度,那么在两个方向上溢出的距离相等
基础效果
<div class="box-wrap">
<div class="box first">第一个盒子</div>
<div class="box">第二个盒子</div>
<div class="box">第三个盒子</div>
<div class="box">第四个盒子</div>
<div class="box last">第五个盒子</div>
</div>
.box-wrap {
width: 1000px;
height: 300px;
background-color: red;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
.box {
width: 300px;
font-size: 20px;
background-color: red;
border: 1px solid yellow;
}
常见的效果
center
方向为row
方向为clumn
flex-start
方向为row
方向为column
flex-end
方向为row
方向为column
stretch
方向为row
方向为column
3.6 align-content
align-content属性主要用来设置浏览器如何沿着弹性盒子布局的交叉轴在内容项和周围分配空间。取值如下
- start:所有行从浏览器的开始边缘开始填充
- end:所有行从浏览器的结束边缘开始填充
- flex-start:所有行从垂直轴的起点开始填充。第一行的垂直轴起点边和容器的垂直轴的起点边对齐,接下来的每一行紧跟前一行。
- flex-end:所有行从垂直轴的末尾开始填充。最后一行的垂直轴的起点边和容器的垂直轴的起点边对齐,所有后续行与前一个对齐。
- center:所有行朝容器的中心填充。每行互相紧挨,相对于容器垂直对齐。容器的垂直轴的起点边与第一行的距离相等于容器的垂直轴的终点边的最后一行的距离。
- space-between:所有行在容器中平均分布。相邻两行间距相等,容器的垂直轴起点边和终点边分别与第一行和最后一行的边对齐。
- space-around:所有行在容器中平均分布。相邻行间距相等,容器的垂直轴的起点边和终点边分别与第一行和最后一行的距离是相邻两行距离的一半
- space-evenly:所有行在容器中平均分布,相邻行间距相等,容器的垂直轴的起点边和终点边分别与第一行和最后一行的距离是相邻两行的距离
- stretch:拉伸所有行来填充剩余空间。剩余空间平均分配给每一行
基础代码
<div class="box-wrap">
<div class="box first">第一个盒子</div>
<div class="box">第二个盒子</div>
<div class="box">第三个盒子</div>
<div class="box">第四个盒子</div>
<div class="box last">第五个盒子</div>
</div>
.box-wrap {
width: 1000px;
height: 300px;
background-color: red;
display: flex;
flex-direction: row;
flex-wrap: wrap;
/* align-items: stretch; */
align-content: start;
}
.box {
width: 300px;
font-size: 20px;
background-color: red;
border: 1px solid yellow;
}
效果
flex-start
在row方向下:
在column方向下:
flex-end
在row方向下:
在column方向下:
center
在row方向下:
在column方向下:
stretch
在row方向下:
在column方向下:
space-between
在row方向下:
在column方向下:
space-around
在row方向下:
在column方向下:
space-evenly
在row方向下:
在column方向下:
4.特别说明
4.1 align-items与align-content的区别
- align-items与align-content的两个属性都是作用在交叉轴上。align-items设置的是flex元素的对齐方式;align-content设置的是flex元素和交叉轴上的空白区域的对齐方式
- align-items只管flex元素的对齐方式,如果出现换行,那么每行元素之间的距离是平均分配的;align-content主要用来设置flex元素与空白区域之间的分配
- align-items只有flex相关的属性,align-content不仅有与flex相关的属性,还有space相关的属性
- align-item的设置对象是行内成员。
- align-content的设置对象是所有行,且只有在多行弹性盒子容器中才生效。
4.2 flex-start,start和left的区别
- 三者设置的都表示左对齐
- flex-start和设置flex-direction的属性有关
- start和元素的writing-mode属性(书写方式)有关
- left若属性flex-direction属性不适用,具体表现等同于start
5. flex属性
flex属性时flex-grow,flex-shrink,flex-basis的缩写。
flex = none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
默认值为:flex-grow:0,flex-shrink:1,flex-basis:auto