Flex布局详解(含实例代码)--flex: 1 1 auto;flex: 0 0 auto是什么意思?

这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战

Flex布局的出现?

在阮一峰老师的文章中(Flex 布局教程:语法篇 - 阮一峰的网络日志)提到了,Flex布局是在什么背景下出现的:布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。

2009年,W3C 提出了一种新的方案----Flex 布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。 

Flex布局是什么?

Flex是Flexible Box的缩写,顾名思义为“弹性布局”,用来为盒装模型提供最大的灵活性。在日常开发中,我还是比较喜欢使用Flex布局的。

任何一个容器都可以指定为Flex 布局。

.box{
  display: flex;
}
复制代码

行内元素也可以使用Flex布局。

.box{
    display:inline-flex;
}
复制代码

webkit内核的浏览器,必需加上-webkit前缀

.box{
    display:-webkit-flex;
    display:flex;
}
复制代码

注:设为flex布局以后,子元素的float、clear和vertical-align属性将失效。

Flex布局相关属性

<div style="display: flex; justify-content: flex-start; width: 500px; height: 100px; border: 1px solid green;">
    <div style="width: 80px; height: 50px; background: blue;"></div>
    <div style="width: 80px; height: 50px; background: red;"></div>
    <div style="width: 80px; height: 50px; background: blue;"></div>
    <div style="width: 80px; height: 50px; background: red;"></div>
    <div style="width: 80px; height: 50px; background: blue;"></div>
    <div style="width: 80px; height: 50px; background: red;"></div>
</div>
复制代码

1.父容器设置justify-content: flex-start;

2.父容器设置justify-content: flex-end;

3.父容器设置justify-content: center;

4.父容器设置justify-content: space-around;表示子容器沿主轴均匀分布,位于首尾两端的子容器到父容器的距离是子容器间距的一半;

5.父容器设置justify-content: space-between:子容器沿主轴均匀分布,位于首尾两端的子容器与父容器相切

6.子容器的设置

(1)属性值flex

子容器是有弹性的(flex 即弹性),它们会自动填充剩余空间,子容器的伸缩比例由flex属性确定。

flex的值可以是无单位数字(如:1, 2, 3),也可以是有单位数字(如:15px,30px,60px),还可以是none关键字。子容器会按照flex定义的尺寸比例自动伸缩,如果取值为none则不伸缩。

(2)主要是由我今天遇到的一个问题讲flex

<div style="display: flex; width: 200px; height: 500px; border: 1px solid green;">
    <div style="flex: 3 0 50px; background: blue;"></div>
    <div style="flex: 2 0 100px; background: red;"></div>
</div>
复制代码

​ 如图所示,蓝色宽为80px;红色宽为120px;

1.flex属性值的构成:flex: flex-grow flex-shink flex-basis;
2.flex-basis表示在不伸缩的情况下子容器的原始尺寸。主轴为横向时代表宽度,主轴为纵向时代表高度。
flex-grow表示子容器弹性伸展的比例。
flex-shink表示子容器弹性收缩的比例。
3.上述代码中,首先左侧div占50px,右侧100px;剩余空间200-100-50 = 50
在剩余空间中,左侧按比例伸展3部分,最后宽度占80
右侧按比例伸展2部分,最后宽占120
复制代码

若将上述代码修改:左侧盒子150px,如图所示,因为没有剩余空间,不会进行伸展;

<div style="display: flex; width: 200px; height: 500px; border: 1px solid green;">
    <div style="flex: 3 0 150px; background: blue;"></div>
    <div style="flex: 2 0 100px; background: red;"></div>
</div>
复制代码

若将上述代码修改:左侧盒子150px,左侧盒子缩放2倍,如图所示,

<div style="display: flex; width: 200px; height: 500px; border: 1px solid green;">
    <div style="flex: 3 2 150px; background: blue;"></div>
    <div style="flex: 2 0 100px; background: red;"></div>
</div>
复制代码

<div style="display: flex; width: 200px; height: 100px; border: 1px solid green;">
    <div style="flex: 3 0; background: blue;"></div>
    <div style="flex: 2 0; background: red;"></div>
</div>
复制代码

注:

(1)如果flex-basis的属性未设置,即flex-basis: 0,那么弹性盒子计算多余空间或者溢出空间的宽度是依据其width的值,如果width未设置,那么是其内容的宽度;

(2)如果同时设置了flex-basis的属性值和width的值,那么将会忽略width的值;

(3)flex-basis可设为百分比,是相对于祖先申明为display:flex的元素而言。

flex: 1 1 auto;flex: 0 0 auto是什么意思?

在上述的属性中,提到了,flex是flex-grow,flex-shrink,flex-basis的缩写,那标题中的数字也就清楚了。

其中flex-grow的默认值为0,表示即便存在剩余空间,也不会放大。

flex-grow的默认值为1,表示如果空间不足,会等比例缩小。

 Flex布局的计算规则

(1)当子盒子小于父容器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
    <style>
        .container {
            display: flex;
            width: 400px;
        }

        .container > div {
            height: 40px;
        }

        .first {
            flex: 1 0 0;
            background-color: red;
        }

        .second {
            flex: 2 0 0;
            background-color: blue;
            margin: 0 50px;
        }

        .third {
            flex: 3 0 0;
            background-color: yellow;
        }
    </style>
</head>
<body>
<div class='container'>
    <div class='first'></div>
    <div class='second'></div>
    <div class='third'></div>
</div>
</body>
</html>
复制代码

上面代码中,我们定义了外层容器width为400px,但是第二个margin为100px。现在flex-basis 属性值为0, 剩下空间为300px。则根据每个盒子flex-grow 属性值及其权重来分配剩余空间

.first宽度 300 *(1/6) = 50px
.second宽度 300 * (2/6) = 100px
.third 宽度 300 *(3/6) = 150

(2)当子盒子超过父容器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>test</title>
    <style>
        .container {
            display: flex;
            width: 200px;
            height: 400px;
            border: 1px solid #c3c3c3;
        }
  
        .first {
            flex-basis: 40px;
            flex-shrink: 1;
            background-color: red;
        }
        .second {
            flex-shrink: 3;
            background-color: blue;
            width: 200px;
        }
        .third {
            flex-basis: 40px;
            flex-shrink: 2;
            background-color: yellow;
        }
    </style>
</head>
<body>
<div class='container'>
    <div class='first'></div>
    <div class='second'></div>
    <div class='third'></div>
</div>
</body>
</html>
复制代码

上面代码, 父容器定义宽度200px,因为flex-basis可替代width属性的。

所以,子项目宽度为 (200+40+40)= 280px,溢出了80px。

首先计算加上权重的值:1*40 + 3 * 200 + 2 * 40 = 720 px

.first 需要缩小的值:(40 * 1/720) * 80 = 4.44px
.second 需要缩小的值:(200 * 3/720) * 80 = 66.67px
.first 需要缩小的值:(40 * 2/720) * 80 = 8.89px
复制代码

那么我们就可以分别得到盒子宽度

35.56px 133.33px 31.11px
复制代码

Happy Ending.

おすすめ

転載: juejin.im/post/7034314491580022820