Flex布局

210 阅读5分钟

一个问题引发的思考

如何让一个元素在其父元素中垂直水平居中?

我们可以有如下几种方式:
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>

效果如下:

可以看到,当设置flex-wrap属性为 nowrap时,如果一行排不下,子元素就会被挤压,实际宽度就不是设置的宽度了.

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/