14
最近项目中涉及到手机端开发,那么flex布局是必不可少的,这里我来重新梳理一下

1. 介绍

flex布局也被成为伸缩盒布局,在flex布局模型中,flex容器的子元素可以在x轴或y轴上进行布局,并且子元素可以伸缩他们的大小,当容器中还有空间它们会伸展以填充容器未使用的空间,当容器空间缩小的时候,他们也会跟着缩小。

2. 应用

2.0 基本概念

主轴与交叉轴,主轴由flex-direction来定义,交叉轴是主轴的垂直方向的轴

- flex-direction:row

clipboard.png

clipboard.png

- flex-direction:column

clipboard.png

clipboard.png

2.1 hello world

伸缩盒布局的应用很简单,只需要为容器元素添加display: flex;即可

    <article class="container_1">
        <section>one</section>
        <section>
            two <br>
            two_1 <br>
            two_2 <br>    
            two_3 <br>
        </section>
        <section>three</section>
    </article>
    
    <style>
        body {
            margin: 0;
            padding: 0;
        }
        .container_1 {
            display: flex;
            justify-content: flex-start;
            /*平分容器,内容居中*/
            /*justify-content: space-around; */
            /*平分容器,内容显示在边缘,其余被空白占*/
            /*justify-content: space-between;*/
            /*内容居中*/
            /*justify-content: center;*/
        }
        .container_1 > section:nth-child(1){
            background-color: lightblue;
        }
        .container_1 > section:nth-child(2){
            background-color: pink;
        }
        .container_1 > section:nth-child(3){
            background-color: lightgreen;
        }
        .container_1 > section:nth-child(4){
            background-color: orange;
        }
    </style>
  • justify-content: flex-start;如图,内容在flex容器的左侧开始排列,空白显示在右侧

clipboard.png

  • justify-content: space-around; 如图,空白会被等分然后填充到子元素的左右

clipboard.png

  • justify-content: space-between; 如图,空白不会出现左右边缘,其余部分空白等分并且进行填充

clipboard.png

  • justify-content: center; 如图,内容居中,空白均分出现在两侧

clipboard.png

  • 如果子元素的内容足够多,将如图显示

clipboard.png

2.2 align-items

用于定义与主轴垂直方向上子元素的显示方式

  • align-items: stretch; 默认值,拉伸

clipboard.png

  • align-items: center; 不拉伸,居中显示

clipboard.png

  • align-items: flex-start;不拉伸,在flex布局的开始位置显示

clipboard.png

  • align-items: flex-end; 不拉伸,在flex布局的结束位置显示

clipboard.png

2.3 flex-direction

定义主轴方向,默认主轴为X周,该属性的取值为 row

  • flex-direction: row; 主轴为X轴

clipboard.png

  • flex-direction: column; 主轴为Y轴

clipboard.png

2.4 flex-wrap

定义是否可以换行,默认值为nowrap

  • flex-wrap:nowrap ,当flex item中的文本足够长的时候也不会导致其他item换行,而是调整其高度以容纳更多内容。

clipboard.png

  • flex-wrap:wrap ,当flex item中的文本足够长的时候会占满整个容器,然后其他item将会导致换行

clipboard.png

2.5 flex-flow

是flex-direction 与 flex-wrap的速写形式。例如

flex-flow: row wrap;

2.6 flex-basis 与 flex-grow

这两个属性定义在flex item上,flex-basis定义了在分配多余空间之前,flex item占据的主轴空间,默认值为auto,与width类似。 flex-grow定了分配多余空间的的规则,例如

    <style>
        .container_1 {
            margin: 0 auto;
            width: 600px;
            display: flex;
            flex-flow: row nowrap;
        }
        .container_1 > section:nth-child(1){
            background-color: lightblue;
            flex-basis: 100px;
            flex-grow: 1;
        }
        .container_1 > section:nth-child(2){
            background-color: pink;
            flex-basis: 100px;
            flex-grow: 2;
        }
        .container_1 > section:nth-child(3){
            background-color: lightgreen;
            flex-basis: 100px;
            flex-grow:1; 
        }
    </style>

    <article class="container_1">
        <section>flex is a new value  added to the CSS display property. Along with inline-flex it causes the element that it applies to to become a flex container, and the element's children to each become a flex item. The items then participate in flex layout</section>
        <section>
            two <br>
            two_1 <br>
            two_2 <br>    
            two_3 <br>
        </section>
        <section>flex is a </section>
    </article>

从上面的样式上,我们可以看出,每个section的flex-basis 基础宽度为100px,flex容器总宽度为600px,这样,剩下的空白区域也就是300px,那么这300像素如何风格呢?这时候就要看没有flex item的flex-grow取值,该值默认为auto,但是我们这里是这么指定的,第一个第三个section为1,第二个section为2,也就是说第一个第三个section各占1/4,也就是75px,第二个section占2/4,也就是150px。所以最后第一个第三个section占175px,第二个section占250px.

clipboard.png

2.7 flex-basis 与 flex-shrink

flex-shrink 同样应用到flex item元素上,与flex-grow作用相反,flex-grow表示当flex-basis的和小于flex容器宽度的时候,如何分配剩余空间进行宽度的增长。而flex-shrink表示当flex-basis的和大于flex容器宽度的时候,按照哪种比例进行缩小

    <style>
        .container_1 {
            margin: 0 auto;
            width: 600px;
            display: flex;
            flex-flow: row nowrap;
        }
        .container_1 > section:nth-child(1){
            background-color: lightblue;
            flex-basis: 300px;
            flex-grow: 1;
            flex-shrink: 1;
        }
        .container_1 > section:nth-child(2){
            background-color: pink;
            flex-basis: 300px;
            flex-grow: 2;
            flex-shrink: 2;
        }
        .container_1 > section:nth-child(3){
            background-color: lightgreen;
            flex-basis: 300px;
            flex-grow:1; 
            flex-shrink: 1;
        }
        .container_1 > section:nth-child(4){
            background-color: orange;
        }
    </style>
    

flex容器的宽度为600px;而flex item加起来为900px,为了能占满flex容器,flex item必须缩小300px; 那么谁应该缩小呢?这时候要看每个flex item上flex-shrink的定义,然后计算出比例

clipboard.png

2.7 flex速写

一般情况下,我们很少使用flex-basis,flex-grow,flex-shrink,而是使用它们的速写形式flex。

flex: flex-grow flex-shrink flex-basis

例如

        .container_1 > section:nth-child(1){
            background-color: lightblue;
            flex-basis: 1 1 300px;
        }
        .container_1 > section:nth-child(2){
            background-color: pink;
            flex-basis:2 2 300px;
        }
        .container_1 > section:nth-child(3){
            background-color: lightgreen;
            flex-basis:1 1 300px;
        }

3. flex实际应用

在实际开发过程中,我们经常会应用到网格布局,一般采用的是float技术,然后封装成一个网格框架进行应用,例如bootstrap的网格布局。但是网格布局也有一些缺陷,比如,它具有两个维度,行与列,再有些项目中我们希望我们的item是一维的,例如:

    <style>
        body {
            margin: 0;
            padding: 0;
        }
        .container_1 {
            display: flex;
            flex-flow: row wrap;
            justify-content: space-around;
        }
        .container_1 > section {
            margin: .5em;
            flex: 1 1 200px;
            background-color: orange;
        }
    </style>

    <article class="container_1">
        <section>
            one <br>
            one <br>
            one <br>
            one <br>
        </section>
        <section>two</section>
        <section>three</section>
        <section>four</section>
        <section>five</section>
        <section>six</section>
        <section>seven</section>
        <section>
            one <br>
            one <br>
            one <br>
            one <br>
        </section>
        <section>two</section>
        <section>three</section>
        <section>four</section>
        <section>five</section>
        <section>six</section>
        <section>seven</section>
    </article>

clipboard.png

clipboard.png

当然,有些同学觉得这样可能和需求不相匹配了,因为我们的代码中flex item的宽度会发生变化,这时候只需要 flex: 0 1 200px;即可,


李春雨
325 声望188 粉丝