深入了解 Flex 属性
你有没有想过 CSS 中的 flex
属性如何工作?它是 flex-grow
,flex-shrink
和flex-basis
的简写。开发中最常见的写法是flex:1
,它表示 flex 项目扩展并填充可用空间。
接下来,我们来详细看看它表示是什么意思。
flex-grow 属性
flex-grow
属性定义项目的放大比例,默认为0
,即如果存在剩余空间,也不放大。flex-grow
的值只接受一个整数。考虑下面代码:
"wrapper">
"item item-1">
"item item-2">
"item item-3">
.wrapper {
display: flex;
flex-wrap: wrap;
}
.item {
flex-grow: 1;
}
注意:
flex-grow
会影响宽度或高度,具体取决于flex-direction
属性。对于以下示例,默认的flex-direction
的值都是row
。
在不使用flex-grow
的情况下,flex 项目的宽度将默认为其初始宽度。但是,使用flex-grow: 1
时,flex 项目会平均剩余可用的空间。
你可能想知道,flex 项目之间的空间是如何分配的?嗯,这是个好问题,稍后会回答。
在下面的图中,是没有使用flex-grow
情况。换句话说,这是它们的自然大小。
要了解 flex 项目宽度的计算方式,可以参考下面的公式。
我们来计算一下文本是 CSS
的项目宽度。
项目宽度 = (( flex-grow / flex-grow 总个数) * 可用空间)+ 初始项目宽度
多个 flex-grow 值
在前面的示例中,所有flex项目的flex-grow
值都相同。现在我们把第一项的flex-grow
值改为2
。这们它又是如何计算?请注意,本示例的可用空间为498px。
上图已经解释的很清楚,这里就不在啰嗦了,还不懂的,可以多看几次。
可以用0
作为flex-grow
的值吗?
当然可以!因为flex-grow
属性接受整数值,所以可以使用0
,可以防止 flex 项目占用可用空间的一种方式。
这在边界情况下非常有用,我们希望使 flex 项目保持其初始宽度。
flex-grow 不能让 flex 项目相等
有一个常见的误解,使用flex-grow
会使项目的宽度相等。这是不正确的,flex-grow
的作用是分配可用空间。正如在公式中看到的,每 flex 项目的宽度是基于其初始宽度计算的(应用flex-grow
之前的宽度)。
如果你想让项目的宽度相等,可以使用flex-basis
,这个在接下来的部分会对此进行讲解。
flex-shrink 属性
flex-shrink
属性定义了项目的缩小比例,默认为1
,即如果空间不足,该项目将缩小。
考虑下面的例子:中间的项目宽度为300px
,flex-shrink
的值为```。如果没有足够的空间来容纳所有的项目,则允许项目缩小宽度。
.item-2 {
width: 300px;
flex-shrink: 1;
}
在下列条件下,浏览器会保持项目宽度为300px
:
所有项目宽度的总和小于包装器宽度 视窗宽度等于或小于项目
下面是项目在不同视口大小下的行为。
如图所示,在视口宽度大于300px
时,宽度为300px
,少于 300px
,该项目的宽度就被压缩成跟视口一样的宽度。
flex-basis 属性
flex-basis
属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto
,即项目的本来大小。
flex-basis
可以设为跟width
或height
属性一样的值(比如350px,默认值为 auto
),则项目将占据固定空间。
.item-1 {
flex-grow: 0;
flex-shrink: 0;
flex-basis: 50%;
}
在上面的例子中,第一项的宽度为50%
。这里需要将flex-grow
重置为0,以防止项目宽度超过50%
。
如果将 flex-basis
设置为 100%
,会怎么样?该项目单独占一行,其他项目将换行。
flex 属性
flex
属性是flex-grow
, flex-shrink
和 flex-basis
的简写,默认值为0 1 auto
。后两个属性可选。这也说 flex 项目会根据其内容大小增长
flex 项目相对大小
.item {
/* 默认值,相当于 flex:1 1 auto */
flex: auto;
}
flex 项目的大小取决于内容。因此,内容越多的flex项目就会越大。
flex 项目绝对大小
相反,当flex-basis
属性设置为0
时,所有flex
项目大小会保持一致。
.item {
/* 相当于 flex: 1 1 0% */
flex: 1;
}
我喜欢 flex 属性的几个点!
顾名思义,此属性可以灵活使用其值。请看下面的例子。
一个值的情况
.item {
flex: 1;
}
上面默认对应的值是 1 1 0
,也就是 flex-grow: 1,flex-shrink:1, flex-basic: 0
。
两个值的情况
.item {
flex: 1 1;
}
上面对应的值是 1 1 0
,也就是 flex-grow: 1,flex-shrink:1, flex-basic: 0
。
一个长度值
如果 flex 值是一个长度值,这会作用于flex-basis
。flex-grow
和flex-shrink
默认为1
。
.item {
flex: 100px;
/* flex: 1 1 100px */
}
使用无单位0
有时,你想把 felx-basis
设置为 0
,你可能会这样写:
.item {
flex: 0;
}
不建议这样做,因为让开发人员和浏览器感到困惑。你到底是要把 flex-grow
或者 flex-shirnk
设置为 0
,还是将 flex-basis 设置为 0
。
所以,你应该添加一个单位,如px
或%
。
.item {
flex: 0%;
/* flex: 1 1 0% */
}
建议使用 flex 简写属性
当你需要设置grow
、shrink
和basis
时,最好使用flex
属性来实现这个目的。
根据 CSS 规范:
建议开发者使用 `flex` 简写来控制灵活性,而不是直接使用它的普通属性,因为简写的可以正确地重置任何未指定的组件以适应常见情景。
flex 用例
用户头像
flexbox 的一个常见用例是用户组件,头像和文本内容应该在同一行。