乐趣区

谈一谈flex布局使用中碰到的一些问题

起因
工作以后由于大量使用到了 flex 布局而碰到了一些尚不清楚的问题,以及一些有意思的特性,在此写篇博客记录一下。
flex 三个值的含义
众所周知,flex 布局所有的属性有两种:一种作用在弹性容器(Flex container)上,一种作用在弹性项目(Flex item)上,而 flex 就是作用在弹性项目上的属性。
flex 是 flex-grow、flex-shrink、flex-basis 三个值的简写,这个值规定了弹性项目如何伸长或压缩以适应弹性容器中的可用空间。
flex-grow 定义弹性项目的放大比列,可以接受数字(小数也可以),不接受负值,默认值是 0。这个值如果为 0 就意味着即使容器内还存在剩余空间,弹性项目也不会放大。
flex-shrink 定义弹性项目的收缩比例,同样接受数字(小数也可以),不接受负值,默认值是 1。如果一个弹性项目的 flex-shrink 设为 0 而其他弹性项目的 flex-shrink 值为 1,则当弹性容器空间不足时,该弹性项目不会被压缩,而其他的弹性项目会被等比例压缩。
flex-basis 定义在分配容器内空间之前,弹性项目占据的主轴空间(不一定是宽度,因为主轴方向可以是纵向的),默认值是 auto。如果对弹性项目同时设置 flex-basis 和 width,width 会被忽略。还要注意当主轴是横向的时候,如果设定了 max-width 或 min-width 会限制弹性项目的宽度。
这里讲一下 flex-basis 取值的情况:

指定的数值,比如以 px、em 为单位的数值。
百分数,取百分数的话就是相对其父弹性容器的宽或高(取决于主轴方向)来计算,如果包含块的尺寸未指定(也就是说父元素的尺寸取决于子元素),那么这时候结果和 auto 一样。

auto 值的意思是基于弹性项目的 width 或 height 调整大小(根据主轴的横向或者纵向),如果没有设置 width 或 height 则根据内容自适应。

设置 flex 之后的弹性项目如何计算宽度
这里给一个代码的例子
<div id=”content”>
<div class=”box1″ style=”background-color:red;”>A</div>
<div class=”box2″ style=”background-color:lightblue;”>B</div>
<div class=”box3″ style=”background-color:yellow;”>C</div>
</div>
#content {
display: flex;
width: 360px;
}

.box1 {
width: 100px;
flex: 1 1 0;
}

.box2 {
width: 100px;
flex: 1 1 0;
}

.box3 {
width: 100px;
flex: 1 1 0;
}
由于 flex-basis 的值为 0,所以此时弹性容器的剩余空间为 360px – 0 * 3 = 360px,由于 3 个元素都设置了 flex-grow: 1,所以剩余空间 3 个元素所占比例为 1:1:1,每个元素的宽度就是 360px / 3 = 120px。
如果把代码改一下呢?
#content {
display: flex;
width: 360px;
}

.box1 {
width: 100px;
flex: 1 1 0;
}

.box2 {
width: 100px;
flex: 1 1 auto;
}

.box3 {
flex: 1 1 200px;
}
此时,弹性容器内剩余宽度为:360px – 0 – 100px – 200px = 60px,3 个元素所占剩余空间比例同样是 1:1:1。那么宽度分别就是:0 + 20px = 20px,100px + 20px = 120px,200px + 20px = 220px。
对应复杂情况的计算,这里有一个回答写得不错:
flex 设置成 1 和 auto 有什么区别
flex 单值、双值、三值的赋值规则是怎么样的
单值情况下:

一个无单位的数字:它会被当作 flex-grow 的值,flex-shrink 为 1,flex-basis 为 0%。

一个有效的宽度值:它会被当作 flex-basis 的值,flex-shrink 和 flex-grow 都是 1。

关键字:比如 auto,none 这两个下文会讲。

双值情况下:
第一个值必须是无单位的数字,它会作为 flex-grow 的值;第二个值可以是:

一个无单位的数字:它会被当作 flex-shrink 的值,而 flex-basis 的值就是 0%。
一个有效的宽度值:它会被当作 flex-basis 的值,flex-shrink 的取值就是 1。

三值情况下:
第一个和第二个值必须是无单位的数,分别作为 flex-grow,flex-shrink,flex-basis 的值;第三个值可以是有效的宽度值,也可以是 auto。
flex: 0,flex: 1,flex: auto,flex: none,flex: 0% 的区别是什么?
讲完了上面的三种赋值方式之后,那么简写就变得很容易理解了:

flex: 0 是 flex: 0 1 0% 的简写

flex: none 是 flex: 0 0 auto 的简写

flex: 1 是 flex: 1 1 0% 的简写

flex: auto 是 flex: 1 1 auto 的简写

flex: 0% 是 flex: 1 1 0% 的简写

小结一下:以上就是对 flex 这个属性取值的梳理,最近一年没有写过博客,最近还是要填一下坑的,前端之路且歌且行~

退出移动版