初探flex布局

1,613 阅读7分钟

给元素设置display: flex 可以将元素设置为 flex 布局, 并可以通过一系列属性的设置来控制其中子元素的布局。

推荐一个练习 flex 布局的小游戏, 很有趣而且可以加强对于 flex 布局的认识。点击(可能需要翻墙);再来个墙内可用链接:点击

1.flex 布局的相关属性

flex布局的相关属性可以分成两类:

  1. 父元素设置的属性,控制父元素内所有子元素的布局
  2. 子元素设置的属性,单独控制某个子元素的位置

详细属性如下:

对父元素 对子元素
flex-direction order
flex-wrap flex-grow
flex-flow flex-shrink
justify-content flex-basis
align-content flex
align-items align-self

下面分别对以上flex属性做讨论。以下部分示例图片的DOM结构如下:

<div class="parent">
    <div class="child">1</div>
    <div class="child">2</div>
    <div class="child">3</div>
    <!-- <div class="child">4</div> -->
    <!-- <div class="child">5</div> -->
</div>

其中.parent为设置display:flex的父元素为绿色,.child为被布局的子元素.

flex布局中涉及flex父元素的主轴和交叉轴的概念,他们是可以改变的,但是本文只取默认情况,即主轴为水平轴,交叉轴是竖直轴,在这篇文章中固定不变。所以文中提到的“左右”是主轴方向,而“上下”就是交叉轴方向。如图:

2. 对 父元素 设置的属性们

对父元素设置的属性可以控制子元素整体的布局方法。

2.1 flex-direction

flex-direction属性设置父元素中子元素的排列方向,取值为:

flex-direction: row || row-reverse || column || column-reverse

其中||符号表示或。

当取值为:

  • row :以行的形式排列,一般为从左到右(==>)排列,示意图如下

  • row-reverse :以行的形式排列,只是方向和row反过来, 一般为从右向左(<==)排列,示意图如下

  • column:以列的形式排列,一般为从上到下排列,示意图如下

  • column-reverse :以列的形式排列,只是方向和column反过来, 一般为从下向上排列,示意图如下

2.2 flex-wrap

这个属性中包含wrap, 顾名思义, 这是个控制子元素换行的属性, 取值为:

flex-wrap: nowrap || wrap || wrap-reverse;
  • nowrap: 不换行,而且会把子元素的宽压缩以确保不溢出父元素

  • wrap: 会换行

  • wrap-reverse: 换行,同时方向反过来

2.3 flex-flow

这是个复合属性, 是前面提到的两个属性的复合,即:

flex-flow: flex-direction flex-wrap

例如:

  • flex-flow: row-reverse nowrap
    相当于:
    flex-direction: row-reverse;
    flex-wrap: nowrap;
    

  • flex-flow: row-reverse wrap
    相当于:
    flex-direction: row-reverse;
    flex-wrap: wrap;
    

2.4 justify-content

这个属性控制子元素在水平方向的对齐方式, 取值如下:

justify-content: flex-start || flex-end || center || space-between || space-around || space-evenly;

当取值分别如下时:

  • flex-start: 左对齐,从左至右排列

  • flex-end : 右对齐,向左排列

  • center: 居中对齐

  • space-between: 每个子元素分散开, 只在中间的子元素之间留空白,两侧的子元素靠边贴着

  • space-around: 子元素分散,每个子元素两侧都有相等大小的空间,但是子元素之间的空间不合并,所以子元素之间的空间是子元素和父元素之间空间的2倍,如图所示:

  • space-evenly: 子元素之间以及子元素和父元素之间的空隙相等, 如图所示:

2.5 align-content

这个属性和 2.4部分的 justify-content 有些相似,不过此属性是控制垂直方向的, 取值有:

align-content: stretch || flex-start || flex-end || center || space-between || space-around || space-evenly;

当取值分别如下时:

  • flex-start: 默认值,从上到下排列:

  • flex-end: 从下到上

  • center: 子元素聚集到中轴线

  • space-between:

  • space-around:

  • space-evenly:

-stretch: 顾名思义,有拉伸的意思,当元素的高度自适应时,会拉伸每个子元素的高度来把父元素填满,如图:

注意:如果给子元素指定了高度,则和默认效果flex-start相同。

2.6 align-items

此属性控制所有子元素在水平方向上的对齐方式,取值可为:

align-items: stretch | flex-start | flex-end | center | baseline;

为更利于此属性的表现,分别调节子元素的高度和字体大小。 当取值分别如下时:

  • flex-start: 默认值,顶部对齐:

  • flex-end: 底部对齐

  • center: 垂直中轴线对齐

  • baseline: 子元素以文字基线对齐

-stretch: 和上面一样,当元素的高度自适应时,会拉伸每个子元素的高度来把父元素填满,如图:

3. 对子元素设置的属性

3.1 order

这个属性可以控制一个子元素相对于其他子元素的前后位置,属性值是整数,默认值是0,可以取负整数。

属性值越小,则相对于其他子元素的位置越靠前,例如对三个子元素分别设置order属性为-3,-2,-1,即

.child:first-child {
    order: -1;
}

.child:nth-child(2) {
    order: -2;
}

.child:nth-child(3) {
    order: -3;
}

由于-3<-2<-1,故第3个子元素在最前,第一个子元素在最后,如图:

在父元素设置为flex-direction: column; 时:

3.2 flex-grow

这个属性表示元素在宽度上对于剩余空间的使用比例,取值为大于等于0的数,默认是0, 即不扩张。这听起来有些抽象,以一个图为例:

上图中父元素宽度为350px,有三个子元素在一行上, 每个子元素宽度都是100px,三个子元素共300px宽度,则父元素在这一行还剩余350-300=50px的主轴宽度空间没有被填满,而这50px的剩余宽度可以分配给这一行的子元素增加到子元素的宽度里。flex-grow属性值决定了一个子元素能拿到的这部分剩余宽度里的多少。

假设三个子元素的flex-grow属性分别设置为1、2、3, 则第一个元素占了总比例的1/(1+2+3)=1/6, 同理第二个元素占了2/6, 第三个元素占了3/6, 所以这3个子元素分别能占有50*(1/6)px50*(2/6)px50*(3/6)=25px,即宽度分别增加了以上的宽度,第3个子元素占有(增加)的宽度最多,第1个子元素增加的宽度最少,即如图:

如果所有子元素的flex取值相加的和小于1,则每个元素的值就是占剩余宽度的比例,例如三个子元素的flex-grow分别设置为0.1、0.2、0.3,则三个元素占有的剩余宽度分别是0.1*50=5px0.2*50=100.3*50=15px, 效果图如下:

3.3 flex-shrink

这个属性设置当父元素宽度不足时子元素的宽度收缩比例, 和上面的flex-grow正好相反, 但是收缩的方法和后者相同。默认值是1, 即收缩相同的宽度。为便于展示, 将子元素宽度都设置成150px, 如图:

flex-shrink就是设置每个子元素相对于150px的收缩比例,决定每个子元素收缩多少宽度的方法和flex-grow相同,举两个例子,当三个子元素都设置成1时, 则每个子元素都收缩1/3*150=50px,如图:
三个子元素分别设置0.1、0.2、0.3,则三个子元素的宽度分别收缩15px、30px、45px,第三个子元素宽度收缩最大,效果如下:

3.4 flex-basis

这个属性设置子元素的宽度,会代替width属性,也就是说如果同时设置了width和flex-basis,则width会被忽略,以flex-basis为准。默认值是auto。

当所有子元素的宽度相加超过父元素的宽度时,所有子元素会等比例收缩,效果相当于设置所有子元素的flex-shrink: 1;

3.5 flex

这是个复合属性:flex: flex-grow flex-shrink flex-basis;,后两个参数是可选的。

3.6 align-self

这个属性控制子元素本身的对齐方式,align-self: auto || flex-start || flex-end || center || baseline || stretch; ,默认值是auto, 表示继承父元素的align-items的属性值。

当设置父元素的align-items: center;时, 对第二个子元素设置align-item属性, 取不同值时的效果如下:

  • auto: 继承自父元素的 align-items

  • flex-start: 对齐顶部

  • flex-end: 对齐底部

  • center: 中轴线对齐

  • baseline: 基线对齐

  • stretch: 拉伸高度以填满父元素的高度

对于子元素, 设置 float, clear, vertical-align等属性不生效。

如有错误,感谢指出!
参考资料:
写给自己看的display: flex布局教程--张鑫旭
MDN