前言
CSS3最喜欢的新属性之一便是flex布局属性,用六个字概括便是简单、方便、快速
Flex 是 Flexible Box 的缩写,意为"弹性布局"
简单来说,就是通过给元素盒子设置一些属性,让元素盒子具有伸缩性
有别于之前的display+position+float布局,flex布局可以简便、完整、响应式地实现各种页面布局
设为 Flex 布局以后,子元素的float、clear和vertical-align属性将失效
概念
首先我们来看下下面这张图,这张图我相信了解过flex布局的人都应该见过
采用flex布局的弹性盒子,称为flex容器(flex container),简称“容器”
盒子里边的子元素称flex项目(flex item),简称“项目”
上图中我们还能看到容器默认存在两根轴:
水平的主轴(main axis)
垂直的交叉轴(cross axis)
主轴和交叉轴的位置是可以变换的,依赖于flex-direction
,默认方向是row
属性
flex属性主要基于两块,一块是使用flex布局的盒子容器,另一块是其子元素
基于盒子容器
-
flex-direction : 主轴方向(子项目的排列方向)
-
flex-wrap : 换行 默认nowrap
-
flex-flow : flex-direction属性和flex-wrap属性的简写 默认row nowrap
-
justify-content : 项目在主轴上的对齐方向
-
align-items : 项目在交叉轴上如何对齐
-
align-content : 多根轴线的对齐方式
基于子元素项目
-
order : 项目的排列顺序
-
flex-grow : 项目的放大比例
-
flex-shrink : 项目的缩小比例
-
flex-basis : 项目占据的主轴空间
-
flex : flex-grow, flex-shrink 和 flex-basis的简写
-
align-self : 单个项目的对齐方式
接下来的内容主要是针对在项目中使用频率比较高的属性
flex-direction 主轴方向(子项目的排列方向)
默认值是row,水平方向,起点在左
与之相反的就是column,垂直方向,起点在上
还有两个属性值为row-reverse和column-reverse,与row和column的区别就在于在于起点相反
有点类似于行内元素不换行与块级元素的换行
justify-content 项目在主轴上的对齐方向
justify-content 是一个非常重要的属性,它的5个属性值都是我们在项目中经常用到的,分别是:
-
flex-start(默认值):左对齐
-
flex-end:右对齐
-
center: 居中
-
space-between:两端对齐,项目之间的间隔都相等
-
space-around:每个项目两侧的间隔相等
align-items 项目在交叉轴上如何对齐
同justify-content一样,也是非常重要的属性,同样也有5个属性值,分别是:
-
flex-start:交叉轴的起点对齐
-
flex-end:交叉轴的终点对齐
-
center:交叉轴的中点对齐
-
baseline: 项目的第一行文字的基线对齐
-
stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度
demo
针对于上面的两种属性,写了个简单的demo,我们可以看下效果,也方便添加后面属性的对比
html
<div class="box">
<div class="item">一</div>
<div class="item" id="item2">二</div>
<div class="item" id="item3">三</div>
<div class="item">四</div>
</div>
css
.box {
width: 700px;
height: 400px;
background-color: #EEB4B4;
display: flex;
justify-content: space-around;
}
.item {
width: 150px;
height: 150px;
font-size: 100px;
border: 1px solid green;
display: flex;
justify-content: center;
align-items: center;
}
效果
flex-grow 项目的放大比例
取值大致有三种情况:
默认值0,即使还存在剩余空间也不放大
所有子项目item取值都为1(或其他相同值),将等分剩余空间(如果有的话)
子项目item取值不相同,比如一个为2,其余都是1,那么属性值为2的item占据的剩余空间是属性值为1的2倍
demo
我们先来设置flex-grow
属性值为1,效果如下:
.item{
...
flex-grow: 1;
}
将id为item2和item3的flex-grow
属性值设置为2
#item2,#item3 {
flex-grow: 2;
}
flex-shrink 项目的缩小比例
这个属性的效果与flex-grow
是相反的,取值也有三种情况:
默认为1,即如果空间不足,该项目将缩小
所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小
子项目item取值不相同,比如一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小
demo
先增加子项目item的数量
.box {
...
<div class="item">五</div>
<div class="item">六</div>
<div class="item">七</div>
}
然后看flex-shrink
的默认值,也就是属性值为1的情况,效果如下:
将id为item2和item3的flex-shrink
属性值设置为0
#item2,#item3 {
flex-shrink: 0;
}
所以,从flex-grow
和flex-shrink
的默认值我们可以知道
flex弹性盒子在存在剩余空间的情况下是默认不具有伸缩性的,在不存在剩余空间的情况下是默认收缩的
flex-basis 定义项目占据的主轴空间(在有剩余空间的情况下)
默认值为auto,项目本身的大小,也就是说从子项目结束后那个位置开始分配项目空间
属性值为width或height属性一样的值(比如350px),代表项目将占据的空间,也就是说从子项目开始的位置分配项目空间
demo
再次将子项目item的数量设为四个,基于最上面的样式设置,给第二个item设置width:200px
,flex-basis
就用默认值
#item2 {
width: 200px;
height: 150px;
}
然后将子项目.item{...}
添加样式flex-basis:170px;
,设置具体的数值
可以看到是从子项目开始的位置,重新分配项目占据空间
flex flex-grow, flex-shrink 和 flex-basis的简写
同样按上面的样式设计,有四种取值情况:
默认值是0 1 auto,代表项目在有剩余空间的情况下,不具有伸缩性;在没有剩余空间的情况下,默认压缩,且从子项目结束后那个位置开始分配项目空间
属性值是auto (1 1 auto) ,从子项目结束的位置分配剩余空间
属性值是none (0 0 auto),不分配剩余空间
属性值是数值(比如1),这三个值分别是
从子项目开始的位置分配剩余空间,同flex-basis:auto
的情况相反
通常在项目中,我们往往是在同级子项目item宽度或高度固定的情况下,让其他子项目占据剩余空间时使用flex:1
比如,在上述情况下我们只取两个子项目item,其中一个item宽度和高度固定,另一个item设置flex:1
,如下;
html
<div class="box">
<div class="item">一</div>
<div class="item" id="item2">二</div>
</div>
css
.box {
width: 700px;
height: 400px;
background-color: #EEB4B4;
display: flex;
justify-content: center;
}
.item {
width: 150px;
height: 150px;
font-size: 100px;
border: 1px solid green;
display: flex;
justify-content: center;
align-items: center;
}
.item2 {
flex: 1;
}
可以看到设置了flex:1
的子项目占据了所有的剩余空间,并始终从头布局(父元素的justify-content: center;
可以相当于未生效)
封装
在项目开发中,我们尽量做到自己封装好flex这些常用的布局方法,比如封装到一个全局样式中,然后在之后的页面css中引入全局样式,具体可以查阅我之前用flex实现的H5页面'头尾固定,中间滚动'的项目,在该项目的global.css中就是我对flex布局常用属性的兼容性的全局封装
.flex {
display: flex;
/* 兼容性 */
display:-webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
}
.direction-column {
-webkit-box-orient:vertical;
-webkit-box-direction:normal;
-moz-box-orient:vertical;
-moz-box-direction:normal;
flex-direction: column;
-webkit-flex-direction:column;
}
以上情况的处理往往是我们写单个网页时。在项目中常常用插件来自动实现兼容性的处理
但是为了方便,在项目中多次用flex布局时,我们也可以对齐进行封装,比如vue,可以参考博客如果说 Flexbox 之前的布局都是错的...