flex 属性
平时在开发中使用 Flex 布局的频率非常高,但是对于flex的几个值的属性始终是含糊不清,此次就来把这些模糊的点搞明白。
flex
是一个简写属性,用于同时设置flex-grow
(放大比例)、flex-shrink
(缩小比例)和flex-basis
(基础大小)这三个子属性。默认值为0 1 auto
,后面两个属性可选。
flex-grow
flex-grow
属性定义项目的放大比例,可以设置任意非负数字(正小数、正整数、0),默认是0,如果存在剩余空间,也不会放大。
接下来我们将
2
的 flex-grow
设置为 1 ,可以看到编号为2
的元素撑满了剩余空间。
如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。
如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍,
2
元素的值为 1 ,3
元素则为 2 。
这里的计算是有一个公式的,首先我们要知道剩余空间是多少,主容器为 500 像素,每个子元素为 100 像素,所以知道我们的剩余空间还有 200 像素 。
1
元素所得的空间: 200(主容器剩余空间) * 1(1元素设置的 flex-grow
值) / 2(flex-grow
总和) = 100像素
1
元素最终的实际宽度为: 100 + 100 = 200 像素
2
元素所得的空间: 200(主容器剩余空间) * 1(2元素设置的 flex-grow
值) / 2(flex-grow
总和) = 100像素
2
元素最终的实际宽度为: 100 + 100 = 200 像素
总结一下公式,flex项最终宽度 = flex项基础宽度 + (容器剩余空间 * flex项设置的 flex-grow
值 / 所有flex项的 flex-grow
和)
flex-shrink
flex-shrink
属性定义了项目的缩小比例,非负数字(正小数、正整数、0),默认值是1,当空间不足时,该项目将缩小,设置了 flex-shrink
为1无变化。
如果所有项目的 flex-shrink
属性都为1,当空间不足时,都将等比例缩小。我们试着改变子元素的宽度,由100变为300,会发现并没有超出容器,而是等分了空间比例。
如果把子元素的
flex-shrink
设置为 0 就不会缩小了。
再来看一下 flex-shrink
的计算规则。
我们父级的容器还是500像素,这次我们将每个子元素设置为150像素,再加一个编号4的子元素,并将2
元素的 flex-shrink
设置为1,4
元素的flex-shrink
为2。此时溢出父容器 100 像素。
接下来我们还需知道总权重, 每个元素的权重计算规则: 每个flex项收缩权重 = flex-shrink
* flex项宽度
2
元素的权重为: 1 * 150 = 150像素
4
元素的权重为: 2 * 150 = 300像素
总权重 = 450像素
2
元素的收缩值为: 100(溢出空间) * ( 150(每个flex
项目权重) / 450(总权重)) = 33.33
2
元素的实际宽度为: 150 - 33.33 = 116.66
4
元素的收缩值为: 100(溢出空间) * ( 300(每个flex
项目权重) / 450(总权重)) = 66.66
4
元素的实际宽度为: 150 - 66.66 = 83.33
总结一下公式,flex项最终宽度 = flex项基础宽度 - (溢出空间 * 每个flex
项目权重 / 总权重)
flex-basis
flex-basis
指定了 flex 元素在主轴方向上的初始大小。他的默认值是auto, 即项目的本来大小。
flex-basis:auto
如果该元素未指定宽度,则宽度将根据内容决定。
定义 flex
元素的 flex-basis
属性。若值为0
,则必须加上单位,以免被视作伸缩性。省略时默认值为 0。(初始值为 auto)
flex: 0 | 1| none | auto
回到我们文章要探讨的问题。flex: 0 | 1| none | auto
分别都是什么意思呢?
flex: 0 1 auto
flex
的默认属性就是 flex: 0 1 auto
。 由上面可知,默认属性代表不放大,可以缩小,宽度大小为自动。如下图没有设置任何属性,子容器的宽度已经超出了父容器(父容器500像素,子容器每个200像素)。可以看到最终每个flex项,都有缩小。
flex: auto
首先来看下设置了flex: auto
是否可以放大,如下父元素还是 500 像素,每个子元素为 100 像素。
可以看出子元素是能放大的。
是否可以缩小呢?来试一下将子元素设置为 300,父元素不变。看到可以缩小。
可以得出结论,flex: auto
相当于 flex: 1 1 auto
, 即可以放大,可以缩小,宽度将根据内容决定。
flex: 0
下图是设置了 flex: 0
,的属性,可以看到元素已经缩小到只有内容了,看一下 MDN ,对于flex的单值解释。
- 一个
<flex-grow>
的有效值:此时简写会扩展为flex: <flex-grow> 1 0
。
那么flex: 0
也就相当于flex: 0 1 0
。不放大,可以缩小。
flex: 1
了解了 flex: 0
, 那么就很容易知道flex:1
相当于 flex: 1 1 0
, 也就是可以放大,可以缩小
flex: none
flex: none
, 相当于 flex: 0 1 auto
, 从属性可以看出是不放大可以缩小。
疑惑
flex: none 和 flex: 0
flex: 0
和 flex: none
都是不可以放大,但是可以缩小,那么他们的区别是什么呢?
它们的区别在于flex-basis
,看一下MDN的描述
当一个元素同时被设置了
flex-basis
(除值为auto
外) 和width
(或者在flex-direction: column
情况下设置了height
) ,flex-basis
具有更高的优先级。
也就是说在有设置宽度的情况下,flex: none
,用的是元素本身的宽度。而flex: 0
则由内容撑开。
flex: auto 和 flex: 1
flex: auto
是 flex: 1 1 auto
的简写,flex: 1
是 flex: 1 1 0
的简写,它们之间的区别还是在于 flex-basis
。
如果容器有足够的空间,flex:1
和 flex:auto
都会平分剩余空间,但是 flex:auto
会保持项目本身的最小宽度。
如果容器没有足够的空间,flex:1
会优先压缩内容,使得所有项目都能等分空间,而 flex:auto
会优先保持内容的完整性,挤压其他项目的空间。
flex: auto;
flex: 1