flex布局的三个属性

82 阅读4分钟

前言

在我们日常开发中,flex布局是最经常使用的,其中用到的比较多的垂直居中:

    .flex-box {
        display: flex;
        justify-content: center;
        align-items: center;
    }

这个是定义在父元素,布局效果在子元素生效的,但是:

  1. 假如所有子元素宽度之和大于父元素的宽度时,子元素会如何变化?
  2. 假如所有子元素宽度之和小于父元素的宽度时,子元素又会如何变化?

在解决这两个问题之前,我们先来了解一下flex-growflex-shrinkflex-basis这三个元素

flex-grow

grow的中文意思是扩大,用来分配父元素剩余空间的相对比例。默认值为0

    .flex-box {
        display: flex;
        width: 300px;
        height: 300px;
        margin: 0 auto;
        background-color: #000;
    }
    .left {
        flex-grow: 1;
        width: 100px;
        background-color: orange;
    }
    .right {
        flex-grow: 0;
        width: 100px;
        background: cyan;
    }

我们设置子元素left和right的宽度之和为200px,而父元素宽度为300px,父元素还有剩余空间,而实际上父元素却会被填满。

image.png

我们先来看一下子元素

image.png

我们会发现子元素left的宽度会变成200px。这是因为在flex-grow的作用下,会将父元素剩余的空间全部分配给了left盒子。

我们修改一下flex-grow属性

    .left {
        ...
        flex-grow: 3
        ...
    } 
    .right {
        ...
        flex-grow: 1
        ...
    }

这样设置也就是剩余空间安装left:right为3:1来处理,多出来的空间为:300px-(100px+100px)=100px
left的宽度:100px+100px * (100 * 3 / (100 * 3 + 100 * 1)) = 175px
right的宽度: 100px +100px * (100 * 1 / (100 * 3 + 100 * 1)) = 125px

当所有的子元素的flex-grow的值是一样的话,那么剩余空间就按照平均分配

flex-shrink

shrink的中文意思是收缩,用来指定flex元素的收缩规则。默认值为1。

    .flex-box {
        display: flex;
        width: 300px;
        height: 300px;
    }

    .left {
        flex-shrink: 3;
        width: 200px;
        background-color: orange;
    }
    .right {
        flex-shrink: 1;
        width: 200px;
        background-color: cyan;
    }

image.png

当所有子元素宽度之和大于父元素宽度时: (200px + 200px > 300px)
由于父元素的宽高都是固定的,所以不能撑大父元素,只能缩小子元素。子元素flex-shrink的比为3:1。

image.png

left的宽度:200px - 100px * (200 * 3/(200 * 3+200 * 1)) = 125px
right的宽度:200px - 100px * (200 * 1/ (200 * 3 + 200 * 1)) = 175px

flex-basis

basis的中文意思是基准,用来指定子元素内容盒尺寸大小。默认值为auto

    .flex-box {
        display: flex;
        width: 300px;
        height: 300px;
        margin: 0 auto;
        background-color: #000;
    }
    .left {
        width: 200px;
        flex-basis: 100px;
        background-color: orange;
    }
    .right {
        width: 100px;
        background-color: cyan;
    }

image.png

观察一下上图,我们发现left的宽度是不是有点奇怪,上面left不是定义了一个widt:200px,可看上去好像并不是如此。

image.png

left的宽度变成了100px,flex-basis是基准,在felx布局下,这个属性的优先级比width高,当flex-basiswidth都存在时,是以前者的值为准的。

总结

  1. flex-grow: 值大于0,主要是 解决父元素宽度大于所有子元素宽度之和时,子元素合理分配父元素剩余空间。 值为0时,子元素盒子空间不做扩大处理。
  2. flex-shrink:值大于0,主要是 *解决父元素宽度小于所有子元素宽度之和时,子元素缩小宽度以适应父元素宽度, *值为0时,子元素盒子空间不做缩小处理。
  3. flex-basis:可以理解为在flex布局下,一个高优先级的宽度

flex

除了上面各自分开使用这三个属性,还可以一起使用这三个属性:

flex: flex-grow flex-shrink flex-basis;

练习题

以下布局在页面上的宽度比是?

.flex {
    display: flex;
    width: 200px;
    height: 100px;
    margin: 0 auto;
    background-color: #000
}
/*子元素*/
.left {
    flex: 3 2 50px
    background-color: orange
}
.right {
    flex: 2 1 200px
    background-color: cyan
}

从上面我们可以看到子元素的flex值太复杂,我们可以先不看前面两个的值,先看最后一值(flex-basis)如果所有子元素的flex-basis之和大于父元素之和,考虑第一个值,如果所有子元素的flex-basis之和小于父元素之和考虑第二个值。

上面所有子元素宽度:50px+200px=250px 大于父元素宽度200px,所以考虑第二个值,也就是子元素left和right的flex-shrink属性比为2:1。
超出的50px这样处理:
left的宽度缩小为:50px-50px*(50px2/(50px2+200px1)) = 33.33
right的宽度缩小为:200px-50px
(200px/(50px2+200px1)) = 166.67

所以宽度之比为 33.34 : 166.66 = 1:5