一个问题引发的思考
如何让一个元素在其父元素中垂直水平居中?
我们可以有如下几种方式:
1.定位布局:
<div style="width:200px;
height:200px;
border:1px solid green;
position:relative;">
<div style="width:100px;
height:100px;
border:1px solid red;
margin:auto;
position:absolute;
top:0;left:0;bottom:0;right:0;">
</div>
</div>
2.百分比布局
<div style="width:200px;
height:200px;
border:1px solid green;
position:relative;">
<div style="width:100px;
height:100px;
border:1px solid red;
margin:auto;
position:absolute;left:50%;top:50%;
margin-left:-50px;margin-top:-50px;">
</div>
</div>
3.table布局
<div style="width:200px;
height:200px;
border:1px solid green;
display:table-cell;
vertical-align:middle;
text-align: center;">
<div style="width:100px;
height:100px;
border:1px solid red;
display:inline-block">
</div>
</div>
可以看到,上面三种方式虽然可以达到我们想要的效果,但是在写法上都挺麻烦.为了方便地解决类似这种特殊布局,CSS3提出了一种新的布局方式,Flex布局.先看看Flex布局实现子元素在其父元素中水平垂直居中的实现方式:
<div style="width:200px;
height:200px;
border:1px solid green;
display:flex;
justify-content:center;
align-items:center;">
<div style="width:100px;height:100px;
background-color: red;">
</div>
</div>
可以看到Flex布局方式较前三种在代码上要简洁很多,核心的代码就三句,分别设置父元素的display、justify-content和align-items属性,下面我们将讲述flex布局中各个属性的值及含义.
Flex布局主要由容器和项目组成,容器和项目构成,容器即父元素,项目即子元素.本人在工作中遇到的大多数都是容器属性的布局,所以这里暂时只介绍容器属性,若多项目属性也感兴趣,请自行在网上查资料学习.(偷个懒,先只总结用的多的容器属性,项目属性以后遇到了再更新补充~~~)
1)display:必写属性.值包含flex和inline-flex,分别为块级Flex布局和行内Flex布局.值得注意的是,设置flex布局后,子元素的float、clear和vertical-align属性都会失效.
2)flex-direction:指定项目排列方向,它有四个值:
row:主轴为水平方向,从左往右布局,这是默认值;
row-reverse:主轴为水平方向,从右往左布局;
column:主轴为垂直方向,从上往下布局;
column-reverse:主轴为垂直方向,从下往上布局;
.box{
width: 120px;
height: 300px;
border:1px solid red;
display: flex;
flex-direction: column-reverse;
}
.items{
width:100px;
height: 80px;
border:1px solid green
}
<div class="box">
<div class='items'>1 </div>
<div class='items'>2 </div>
<div class='items'> 3</div>
</div>
上面代码将flex-direction属性设为column-reverse,即垂直方向从下往上布局,效果如下图:

3)flex-wrap:这个属性规定了项目在一条轴线上排不下时该如何排列,它有三个值:
nowrap:不换行,默认值; 注意,此时给子元素设置的width会失效;
wrap:换行,依次往下排列;
wrap-reverse:从下往上排列;
.box{
width: 120px;
height: 100px;
border:1px solid red;
display: flex;
flex-wrap: nowrap;
}
.items{
width:100px;
height: 80px;
border:1px solid green;
}
<div class="box">
<div class='items'>1 </div>
<div class='items'>2 </div>
<div class='items'>3</div>
</div>
效果如下:

4)flex-flow:flex-direction和flex-wrap的简写形式,默认为row nowrap;
例如,flex-flow: row-reverse wrap;
5)justify-content:这个属性定义了项目在主轴上的对齐方式,包括以下几个值: flex-start:左对齐,默认值; flex-end:右对齐; certer:居中; space-between:两端对齐; space-around:每个项目两侧的间隔相等. 下面以space-between为例,展示下这个属性的效果:
.box{
width: 500px;
height: 100px;
border:1px solid red;
display: flex;
justify-content: space-between;
}
.items{
width:100px;
height: 80px;
border:1px solid green;
}
<div class="box">
<div class='items'>1 </div>
<div class='items'>2 </div>
<div class='items'>3</div>
</div>

6)align-items:指定项目在交叉轴上如何对齐,有如下几个值:
flex-start: 顶部对齐;
flex-end: 底部对齐;
center: 中线对齐;
baseline: 根据它们的第一行的文字对齐;
stretch: 若项目未设置高度,则项目将在交叉轴方向拉伸填充整个容器,这个是默认值.
.box{
width: 500px;
height: 100px;
border:1px solid red;
display: flex;
justify-content: space-between;
}
.items{
width:100px;
height: 80px;
border:1px solid green;
}
<div class="box">
<div class='items'>1 </div>
<div class='items'>2 </div>
<div class='items'>3</div>
</div>

7)align-content:用来定义项目多个轴线(换行后)在交叉轴上的对齐方式,如果项目只有一根轴线,该属性不起作用.
flex-start:顶部对齐;
flex-end:底部对齐;
certer:与交叉轴中点居中;
space-between:与交叉轴两端对齐,轴线之间的间隔平均分布;
space-around:每根轴线两侧的间隔都相等,轴线之间的间隔比轴线与边框间隔大一倍.
stretch:轴线占满整个交叉轴,每个项目会被拉伸直至填满交叉轴,这个是默认值.
.box{
width: 320px;
height: 300px;
border:1px solid red;
display: flex;
flex-wrap: wrap;
align-content: space-around;
}
.items{
width:100px;
height: 80px;
border:1px solid green;
}
<div class="box">
<div class='items'>1 </div>
<div class='items'>2 </div>
<div class='items'>3</div>
</div>
效果如下:

以上就是flex布局中的容器属性的介绍了,本文中对于每个属性的值只给了一个例子,感兴趣的可以自己试试其他的值的效果.
关于flex布局,网上有一个很好玩的小游戏,可以帮助理解flex布局, blog.xiaoboswift.com/flexbox/