1.基本概念

什么是flex?

flex全称是FlexibleBox,即弹性盒子,用来进行弹性布局,弹性布局也是目前前端应用最广的布局之一。

flex布局的优点,为什么要用flex布局?

1.可以为盒子模型提供最大的灵活性,任何一个容器都可以指定为flex布局。

2.更加符合响应式设计的特点,方便页面在不同设备上的布局显示。

主要概念介绍
在这里插入图片描述

main axis:主轴,如果内部元素是横向排列的,那么此时x轴是主轴,如果内部元素是纵向排列的,则主轴为y轴。
cross axis:交叉轴,与主轴垂直的轴。
main start(end):主轴的开始(结束)位置。
cross start(end):交叉轴的开始(结束)位置。
main size:子元素相对于主轴的大小。
cross size:子元素相对于交叉轴的大小。

注意:1.以子元素的排列方向为基准,区分主轴和交叉轴。
           2.main size和cross size不能简单理解为内部子元素的宽度和高度,而是依据主轴和交叉轴来区分。

2.flex-direction的用法

作用:设置子元素在父元素盒子中的排列方式。

属性值作用
row默认值,按从左到右的顺序显示
row-reverse与row相同,但是以相反的顺序
column将项目垂直显示,按照从上到下的顺序
column-reverse与column相同,但是以相反的顺序

实例:

  1. 设置一个width为500px的绿色大盒子div0,display设置为flexflex-direction设置为 row。内部嵌套四个长宽为100px*100px的黄色小盒子,且四个小盒子横向排列,效果如下:
flex-direction: row;

代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .div0 {
            width: 500px;
            background: green;
            display: flex;
            flex-direction: row;
        }
        .div0 div {
            width: 100px;
            height: 100px;
            background-color: yellow;
        }
    </style>
</head>
<body>
    <div class="div0">
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
    </div>
</body>
</html>

将上述代码中的flex-direction: row;属性值分别改为row-reverse,column,column-reverse,得到如下效果,

flex-direction: row-reverse;
flex-direction: column;
flex-direction: column-reverse;

建议大家自己动手尝试一下!

  1. 将div0的width设置为300px,而内部四个小盒子宽度之和却达到了400px,此时大盒子“装不下”四个小盒子了,页面会如何显示呢?
    代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .div0 {
            width: 300px;
            background: green;
            display: flex;
            flex-direction: row;
        }
        .div0 div {
            width: 100px;
            height: 100px;
            background-color: yellow;
        }
    </style>
</head>
<body>
    <div class="div0">
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
    </div>
</body>
</html>

效果如下:
在这里插入图片描述
可以看到,此时每个小盒子的宽度自动压缩到75px,由此可知,子元素的宽度大于外部盒子宽度时,flex布局会自动压缩子元素以适应外部盒子的大小

3.flex-wrap的用法

前文说到,子元素的宽度大于外部盒子宽度时,flex布局会自动压缩子元素以适应外部盒子的大小,有没有什么方法能不用压缩子元素呢?
答案是肯定的,那就是用flex-wrap,实际项目中响应式设计大都会用到该方法。

作用:子元素在父元素盒子中是否换行(列)。

属性值作用
nowrap默认值,不换行(列)
wrap换行(列)
wrap-reverse换行或还列,但以相反的顺序

实例:
在第二节中的实例2基础上,加上flex-wrap: wrap;使子元素换行而不会被压缩。
代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .div0 {
            width: 300px;
            background: green;
            display: flex;
            flex-direction: row;
            flex-wrap: wrap;
        }
        .div0 div {
            width: 100px;
            height: 100px;
            background-color: yellow;
        }
    </style>
</head>
<body>
    <div class="div0">
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
    </div>
</body>
</html>

效果如下:
在这里插入图片描述
剩下的属性值,有兴趣的话可以自行尝试一下,这里不多赘述。

注意:flex-directionflex-wrap可以简写成flex-flow,先写flex-direction属性值,再写flex-wrap属性值,语法格式如下:

flex-flow: <flex-direction> || <flex-wrap>

4. justify-content的用法

还是上面换行的例子,将div0的width设置为380px时,就会发现子元素之间有很多剩余空间,影响美观,如下图所示。
在这里插入图片描述

为了解决上述问题,我们通常在父级盒子中使用 justify-content来调整子元素之间的间距。

作用:当内部盒子有剩余空间时,用来将剩余空间调整为子元素之前的间距。

属性值属性
flex-start默认值,从左到右,挨着行的开头
flex-end从右到左,挨着行的结尾
center居中显示
space-between平均分布在改行上,两边不留间隔空间
space-around平均分布在该行上,两边留有一半的间隔空间

实例:
justify-content方法,将上一个例子中的剩余空间进行设置。
代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .div0 {
            width: 380px;
            background: green;
            display: flex;
            flex-direction: row;
            flex-wrap: wrap;
            justify-content: center;
        }
        .div0 div {
            width: 100px;
            height: 100px;
            background-color: yellow;
        }
    </style>
</head>
<body>
    <div class="div0">
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
    </div>
</body>
</html>

效果如下:
在这里插入图片描述
将上述代码中justify-content: center;的属性值分别改为flex-endspace-betweenspace-around,效果如下:

justify-content: flex-end;
justify-content: space-between;
justify-content: space-around;

5.align-items的用法

作用:设置每个flex元素在交叉轴上的默认对齐方式

属性值作用
flex-start位于容器的开头
flex-end位于容器的结尾
center居中显示

实例:
设置一个width为400px,height为400px的绿色大盒子div0,display设置为flexflex-direction设置为 row。内部嵌套四个长宽为100px*100px的黄色小盒子,效果如下:
在这里插入图片描述
如何改变内部四个小盒子的位置呢?
通过align-items属性!
align-items:center;设置子元素居中
代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .div0 {
            width: 400px;
            height: 400px;
            background: green;
            display: flex;
            flex-direction: row;
            flex-wrap: wrap;
            justify-content: space-around;
            align-items: center;
        }
        .div0 div {
            width: 100px;
            height: 100px;
            background-color: yellow;
        }
    </style>
</head>
<body>
    <div class="div0">
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
    </div>
</body>
</html>

效果如下:
在这里插入图片描述
至于flex-startflex-end两种属性值,感兴趣的可以自行尝试,这里不做赘述。

注意:例子中的flex-direction属性值为row,此时的主轴为横向,交叉轴为纵向flex-startcenterflex-end都是相对于交叉轴来说的,即上中下;若flex-direction属性值为column,则flex-startcenterflex-end表示左中右

6.针对flex布局子对象的属性

前面介绍的都是针对父对象的属性设置,本节介绍几个常用的针对子对象的属性。

属性值作用
flex-basis设置弹性盒子的伸缩基准值
flex-grow设置弹性盒子的扩展比例
flex-shrink设置弹性盒子的缩小比例
flexflex-basis, flex-grow,flex-shrink的缩写

实例:

  1. 设置一个width为400px,height为500px背景为紫色的盒子div0,再嵌套两个width为200px,height为200px背景为黄色的子盒子。效果如下:
    在这里插入图片描述
    通过flex-basis来设置子盒子的宽度,并查看效果。
    代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .div0 {
            display: flex;
            width: 400px;
            height: 500px;
            background-color: blueviolet;
        }
        .div0 div {
            width: 200px;
            height: 200px;
            background-color: yellow;
        }
        .div0 div:nth-child(1) {
            flex-basis: 50px;
        }
        .div0 div:nth-child(2) {
            flex-basis: 100px;
        }
    </style>
</head>
<body>
    <div class="div0">
        <div>1</div>
        <div>2</div>
    </div>
</body>
</html>

效果如下:
在这里插入图片描述
此时可以看到,第一个盒子的宽度变成了50px,第二个盒子的宽度变成了100px。注意,此时子盒子原本的width:200px;已失效!!!

  1. 对上面1中的例子中的子盒子用flex-grow进行扩充。
    代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .div0 {
            display: flex;
            width: 400px;
            height: 500px;
            background-color: blueviolet;
        }
        .div0 div {
            width: 200px;
            height: 200px;
            background-color: yellow;
        }
        .div0 div:nth-child(1) {
            flex-basis: 50px;
            flex-grow: 1;
        }
        .div0 div:nth-child(2) {
            flex-basis: 100px;
            flex-grow: 3;
        }
    </style>
</head>
<body>
    <div class="div0">
        <div>1</div>
        <div>2</div>
    </div>
</body>
</html>

效果如下:
在这里插入图片描述
可以看到,第一个子盒子宽度扩展到了112.5px,第二个盒子的宽度扩展到了287.5px,盒子的宽度是如何从50px扩展到112.5px,从100px扩展到287.5px的呢?

首先我们设置了第一个子盒子的flex-grow: 1;第二个盒子的flex-grow: 3;,这个意思是:将剩余的空间分成1+3份,第一个子盒子占1份,第二个子盒子占3份。
剩余空间:父盒子宽度-子盒子宽度=400 - (50+100)=250px
每一份宽度:250/4=62.5px
第一个子盒子占一份:50+62.5=112.5px
第二个子盒子占三份:100+62.5*3=287.5px

  1. 设置一个width为400px,height为500px背景为紫色的盒子div0,再嵌套两个width为200px,height为200px背景为黄色的子盒子。通过flex-basis将第一个盒子的宽度改为250px,第二个盒子的宽度改为300px,此时子盒子的宽度和就会超过父盒子的宽度,效果如下:
    在这里插入图片描述
    可以看到,此时flex布局自动将超出部分缩小到了父盒子的宽度。设置flex-shrink:0;不允许缩小。代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .div0 {
            display: flex;
            width: 400px;
            height: 500px;
            background-color: blueviolet;
        }
        .div0 div {
            width: 200px;
            height: 200px;
            background-color: yellow;
        }
        .div0 div:nth-child(1) {
            flex-basis: 250px;
            flex-grow: 1;
            flex-shrink: 0;
        }
        .div0 div:nth-child(2) {
            flex-basis: 300px;
            flex-grow: 3;
            flex-shrink: 0;
        }
    </style>
</head>
<body>
    <div class="div0">
        <div>1</div>
        <div>2</div>
    </div>
</body>
</html>

效果如下:
在这里插入图片描述
此时可以看到,在不允许缩小的情况下,子盒子宽度超出了父盒子的范围。
有兴趣的话可以试试两个子盒子分别设置flex-shrink: 1; flex-shrink: 3;,改效果原理和flex-grow一样,将超出父盒子的宽度分为4份,第一个子盒子占1份,第二个占3份,按照这样的比例缩小。

注意:flex-growflex-shrinkflex-basis可以简写成flex,先写flex-grow属性值,再写flex-shrink属性值,最后写flex-basis属性值,语法格式如下:

flex: <flex-grow> || <flex-shrink> || <flex-basis>

7.针对flex布局子对象属性的几种简写

属性作用
flex: auto;flex: 1 1 auto;
flex: none;flex: 0 0 auto;
flex: 0%;flex: 1 1 0%;
flex: 100px;flex: 1 1 100px;
flex: 1;flex: 1 1 0%;

这部分可以自己动手试试,不做赘述。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐