关于html5:flex布局中的flexbasisflexgrowflexshrink到底咋回事儿

10次阅读

共计 3833 个字符,预计需要花费 10 分钟才能阅读完成。

flex 布局是十分弱小的布局形式,它能轻易实现咱们能想到的大部分布局,相似圣杯布局、双飞翼布局等等,它非常灵活,兼容性也很好,在我的项目中常常被应用到。大多数同学应该都是从阮一峰老师的 这篇博文 理解到 flex 的,虽是 15 年写的,但毫不过期,仍然有很强的引导性。

然而阮老师对于 flex-basis、flex-grow、flex-shrink 这三个属性只是一笔带过,没有去深刻讲它,我始终对这三个属性都是云里雾里的(脑壳笨🤣),在网上也未找到很好的解说,最近写页面写的比拟多,始终在用 flex 布局,有没搞懂的感觉很不难受,故本人钻研了一下,做下记录,若有谬误欢送斧正

根底 demo
HTML

<div class=”box”>

<span class="item">1</span>
<span class="item">2</span>
<span class="item">3</span>

</div>

CSS

.box {

width: 300px;
height: 100px;
border: 1px solid black;

display: flex;

}
.item {

font-size: 25px;
color: white;
display: inline-block;
text-align: center;
line-height: 100px;

}

flex-basis
flex-basis 属性定义了在调配多余空间之前,我的项目占据的主轴空间(main size)。浏览器依据这个属性,计算主轴是否有多余空间。它的默认值为 auto,即我的项目的原本大小。—— 阮老师博客定义

咱们先给每个 item 一个不同的 width

.item:nth-child(1) {

width: 50px;
background-color: red;

}
.item:nth-child(2) {

width: 100px;
background-color: rgb(0, 204, 255);

}
.item:nth-child(3) {

width: 100px;
background-color: rgb(0, 255, 64);

}

(容器 flex 布局,flex-direction 默认为 row,程度排列。align-items 默认为 stretch,item 未设高度,填满整个容器。咱们没有给 item 设置 flex-basis 属性,默认值为 auto)

当初咱们给第一个 item 给个 flex-basis 属性,值为 100px

.item:nth-child(1) {

width: 50px;
background-color: red;
flex-basis: 100px;

}

咱们发现第一个 item 的 width 被 flex-basis 代替了,所以咱们可得出 论断

item 的 flex-basis 未设置或为 auto 时,item 的 width 无效
item 的 flex-basis 有值时,width 就被代替,有效了
flex-grow
flex-grow 属性定义我的项目的放大比例,默认为 0,即如果存在残余空间,也不放大。—— 阮老师博客定义

咱们还是先给每个 item 一个不同的 width(跟下面的第一个一样的,我只是搬下来了)

.item:nth-child(1) {

width: 50px;
background-color: red;

}
.item:nth-child(2) {

width: 100px;
background-color: rgb(0, 204, 255);

}
.item:nth-child(3) {

width: 100px;
background-color: rgb(0, 255, 64);

}

父容器 div.box 的 width 有 300px,然而三个 item 加起来才 250px,还有 50px 的残余空间。若是此时你想这 50px 的残余空间被这三个我的项目以你的安顿来占满,那么 flex-grow 就排上用场了

flex-grow 属性默认为 0,就是不占残余空间。咱们若想第一个 item 把残余空间全占了,那就

.item:nth-child(1) {

width: 50px;
background-color: red;
flex-grow: 1;

}
.item:nth-child(2) {

width: 100px;
background-color: rgb(0, 204, 255);

}
.item:nth-child(3) {

width: 100px;
background-color: rgb(0, 255, 64);

}

此时第一个 item 的 flex-grow 是 1,另外两个都是 0,天然就被第一个独吞了

若是咱们想第一二三个 item 以一、二、三的比例来瓜分残余空间

.item:nth-child(1) {

width: 50px;
background-color: red;
flex-grow: 1;

}
.item:nth-child(2) {

width: 100px;
background-color: rgb(0, 204, 255);
flex-grow: 2;

}
.item:nth-child(3) {

width: 100px;
background-color: rgb(0, 255, 64);
flex-grow: 3;

}

那么第一个 item 理论宽度就是:50 + (1 / 6) * 50 = 58.333333333

第二个:100 + (2 / 6) * 50 = 116.6666666666

第三个:100 + (3 / 6) * 50 = 125

flex-grow 属性默认值为 0,不会参加瓜分残余空间
残余空间会按 item 的 flex-grow 属性值来瓜分
flex-shrink
flex-shrink 属性定义了我的项目的放大比例,默认为 1,即如果空间有余,该我的项目将放大。—— 阮老师博客定义

依照常规,还是给每个 item 不同的 width,这次不同一点,宽度和要超过 div.box 的 width

.item:nth-child(1) {

width: 100px;
background-color: red;

}
.item:nth-child(2) {

width: 150px;
background-color: rgb(0, 204, 255);

}
.item:nth-child(3) {

width: 200px;
background-color: rgb(0, 255, 64);

}

可发现,尽管三个 item 的宽度和超过了 div.box 的 width,超出局部有 150px,然而并没有超出 div.box,而是每个 item 都被”挤回去了“,这是因为每个 item 的 flex-shrink 属性默认都是 1,它会按宽度比例放大

flex-shrink 和 flex-grow 不同,它会综合思考每个 item 的宽度比和 flex-shrink 比,最终顺次相乘做最初的比拟,再用这个比值作为被缩减的宽度比

flex-grow 之所以只看 flex-grow 的比值,不思考宽度之比,是因为它只是去占有残余空间,而跟每个 item 本身的 width 无关

咱们可通过 计算 验证:

它们的宽度比为:2:3:4

flex-shink 比为:1:1:1

则被缩减的宽度比为:2:3:4

所以第一个 item 的理论宽度:100 – (150 / 9) * 2 = 66.66666666

第二个:150 – (150 / 9) * 3 = 100

第三个:200 – (150 / 9) * 4 = 133.3333333333

咱们能够再验证一个简单点的:

.item:nth-child(1) {

width: 100px;
background-color: red;
flex-shrink: 3;

}
.item:nth-child(2) {

width: 150px;
flex-shrink: 4;
background-color: rgb(0, 204, 255);

}
.item:nth-child(3) {

width: 200px;
flex-shrink: 2;
background-color: rgb(0, 255, 64);

}

宽度比:2:3:4

flex-shrink 比:3:4:2

被缩减的宽度比:3:6:4

所以第一个:100 – (150 / 13) * 3 = 65.384615384615384615

第二个:150 – (150 / 13) * 6 = 80.7692307692307692307

第三个:200 – (150 / 13) * 4 = 153.84615384615384615

教训证是正确的

还有个问题,如果每个 item 的 flex-shrink 的值都为 0 会怎么呢?

聪慧的你应该想到了,会超出父元素 div.

总结

  1. flex-basis
    item 的 flex-basis 未设置或为 auto 时,item 的 width 无效
    item 的 flex-basis 有值时,width 就被代替,有效了
  2. flex-grow
    flex-grow 属性默认值为 0,不会参加瓜分残余空间
    残余空间会按所以 item 的 flex-grow 属性值的比值来瓜分
    flex-grow 之所以只看 flex-grow 的比值,不思考宽度之比,是因为它只是去占有残余空间,跟每个 item 本身的 width 无关
  3. flex-shrink
    flex-shrink 属性默认为 1,它会按宽度比例放大,为 0 时,不会放大
    flex-shrink 和 flex-grow 不同,它会综合思考每个 item 的宽度比和 flex-shrink 比,最终顺次相乘做最初的比拟,再用这个比值作为被缩减的宽度比
    当父容器外部的 item 宽度和超过父容器宽度时且 item 的 flex-shrink 都为 0 时会超出父容器

原文链接:https://blog.csdn.net/qq_4170…

正文完
 0