Flexbox 基础概念
弹性盒子布局 模块(通常称为 Flexbox)是一种用于在项目之间分配空间的一维布局模型,并包含许多对齐功能。本文概述了 Flexbox 的主要功能,我们将在这些指南的其余部分更详细地探讨这些功能。
当我们将 Flexbox 描述为一维时,我们指的是 Flexbox 一次处理一个维度上的布局——作为一行或一列。这与 CSS 网格布局 的二维模型形成对比,后者同时控制列和行。
Flexbox 的两个轴
使用 Flexbox 时,您需要考虑两个轴——主轴和交叉轴。 主轴 由 flex-direction
属性定义,而 交叉轴 则垂直于它。我们使用 Flexbox 所做的一切都参考这些轴,因此从一开始就了解它们的工作原理非常有价值。
主轴
主轴 由 flex-direction
定义,它有四个可能的值
row
row-reverse
column
column-reverse
如果您选择 row
或 row-reverse
,则您的主轴将沿行的**内联方向**运行。
选择 column
或 column-reverse
,您的主轴将沿**块方向**运行,从页面顶部到底部。
交叉轴
交叉轴 垂直于主轴。因此,如果您的 flex-direction
(主轴)设置为 row
或 row-reverse
,则交叉轴沿列运行。
如果您的主轴是 column
或 column-reverse
,则交叉轴沿行运行。
起始行和结束行
另一个重要的理解领域是 Flexbox 对文档的书写模式不做任何假设。Flexbox 不仅仅假设所有文本行都从文档的左上角开始并向右侧运行,新行出现在另一行下方。相反,它支持所有书写模式,就像其他 逻辑属性和值 一样。
您可以在后面的文章中 阅读有关 Flexbox 和书写模式之间关系的更多信息;但是,以下描述应该有助于解释为什么我们在描述 Flex 项目的流动方向时不谈论左右和上下。
如果flex-direction
属性的值为row
,并且我使用的是英语,那么主轴的起始边将在左侧,结束边将在右侧。
如果我使用的是阿拉伯语,那么我的主轴的起始边将在右侧,结束边将在左侧。
在这两种情况下,交叉轴的起始边都在弹性容器的顶部,结束边都在底部,因为这两种语言都具有水平书写模式。
过一段时间后,思考起始和结束而不是左右会变得自然,并且在处理其他布局方法(例如遵循相同模式的CSS网格布局)时会对您有所帮助。
Flex 容器
初始值
与CSS中的所有属性一样,定义了一些初始值,因此新弹性容器的内容将以以下方式表现
- 项目以行显示(
flex-direction
属性的默认值为row
)。 - 项目从主轴的起始边开始。
- 项目在主尺寸上不会拉伸,但可以收缩(弹性项目的
flex-grow
属性的默认值为0
,其flex-shrink
属性的默认值为1
)。 - 项目将拉伸以填充交叉轴的大小(
align-items
属性的默认值为stretch
)。 - 弹性项目的
flex-basis
属性的默认值为auto
。这意味着在每种情况下,它都将等于弹性项目在水平书写模式下的width
,以及在垂直书写模式下的弹性项目height
。如果相应的width
/height
也设置为auto
,则改为使用flex-basis
的content
值。 - 所有项目都将位于一行中(
flex-wrap
属性的默认值为nowrap
),如果它们的组合width
/height
超过包含元素的width
/height
,则会溢出其容器。
其结果是,您的所有项目都将排成一行,使用内容的大小作为其在主轴上的大小。如果项目数量超过容器所能容纳的数量,它们不会换行,而是会溢出。如果某些项目比其他项目更高,则所有项目都将在交叉轴的整个长度上拉伸。
您可以在下面的实时示例中看到它的外观。尝试编辑项目或添加其他项目以测试弹性盒的初始行为。
更改flex-direction
将flex-direction
属性添加到弹性容器允许我们更改弹性项目显示的方向。设置flex-direction: row-reverse
将使项目沿行显示,但是起始线和结束线将被切换。
如果我们将flex-direction
更改为column
,则主轴会切换,我们的项目现在会以列的形式显示。设置column-reverse
,起始线和结束线将再次被切换。
下面的实时示例将flex-direction
设置为row-reverse
。尝试其他值 - row
、column
和column-reverse
- 以查看内容发生了什么变化。
使用 flex-wrap 的多行 Flex 容器
虽然弹性盒是一维模型,但可以使弹性项目跨多行换行。如果这样做,您应该将每一行视为一个新的弹性容器。任何空间分配都将在每一行中进行,而不参考前一行或后续行。
要导致换行行为,请添加属性flex-wrap
,其值为wrap
。现在,如果您的项目太大而无法在一行中全部显示,它们将换行到另一行。下面的实时示例包含已设置width
的项目。项目的总宽度对于弹性容器来说太宽了。由于flex-wrap
设置为wrap
,因此项目跨多行换行。如果将其设置为nowrap
(初始值),它们将缩小以适应容器。它们会缩小,因为它们使用的是初始弹性盒值,包括flex-shrink: 1
,这允许项目缩小。如果项目无法缩小,或者无法缩小到足以适应容器的大小,则使用nowrap
会导致溢出。
在指南掌握弹性项目的换行中了解有关换行弹性项目的更多信息。
flex-flow 简写
您可以将两个属性flex-direction
和flex-wrap
组合到flex-flow
简写中。
在下面的实时示例中,尝试将第一个值更改为flex-direction
允许的值之一 - row
、row-reverse
、column
或column-reverse
,并将第二个值更改为wrap
和nowrap
。
应用于 Flex 项目的属性
要控制每个弹性项目的大小,我们通过三个属性直接定位它们
我们将在下面简要介绍这些属性,但是如果您需要更全面的信息,请查看控制弹性项目在主轴上的比例指南。
在我们理解这些属性之前,我们需要考虑**可用空间**的概念。当我们更改这些弹性属性的值时,我们所做的是更改可用空间在我们项目中的分配方式。当我们开始对齐项目时,可用空间的概念也很重要。
如果我们在宽度为500像素的容器中有三个宽度为100像素的项目,那么我们布置这些项目所需的空间为300像素。这留下了200像素的可用空间。如果我们不更改初始值,则弹性盒会将该空间放在最后一个项目之后。
如果我们希望项目增长并填充空间,那么我们需要有一种方法在项目之间分配剩余的空间。我们应用于项目本身的flex
属性使我们能够指示如何将该可用空间分配给同级弹性项目。
flex-basis属性
flex-basis
定义了该项目在可用空间方面的大小。此属性的初始值为auto
- 在这种情况下,浏览器会查看项目是否具有大小。在上面的示例中,所有项目的宽度都为100像素。这用作flex-basis
。
如果项目没有大小,则内容的大小将用作flex-basis
。这就是为什么当我们只是在父元素上声明display: flex
来创建弹性项目时,所有项目都会移到一行并只占用显示其内容所需的尽可能小的空间。
flex-grow属性
如果flex-grow
属性设置为正整数,并且有可用空间,则弹性项目可以沿主轴从其flex-basis
增长。项目是否拉伸以占用该轴上的所有可用空间,或者只是部分可用空间,取决于其他项目是否也允许增长以及其flex-grow
属性的值。
每个具有正值的项目都会根据其flex-grow
值消耗一部分可用空间。如果我们在上面的示例中为所有项目都提供flex-grow
值为1,则弹性容器中的可用空间将在我们的项目之间平均分配,并且它们将拉伸以填充主轴上的容器。如果我们给第一个项目一个flex-grow
值为2,而其他项目每个值为1,则总共有4个部分;可用空间的2个部分将分配给第一个项目(在上面的示例中,为200像素中的100像素),其他两个项目每个部分为1(在总共200像素中,每个为50像素)。
flex-shrink属性
flex-grow
属性用于在主轴上添加空间,而flex-shrink
属性控制如何将其移除。如果我们没有足够的空间在容器中布置我们的项目,并且flex-shrink
设置为正整数,则该项目可以小于flex-basis
。与flex-grow
一样,可以分配不同的值以导致一个项目比其他项目收缩得更快 - 为flex-shrink
设置较高值的项目将比其具有较低值的同级项目收缩得更快。
项目可以缩小到其min-content
大小。在计算将发生的实际收缩量时,会考虑此最小大小,这意味着flex-shrink
的行为可能不如flex-grow
一致。因此,我们将在文章控制项目在主轴上的比例中更详细地了解此算法的工作原理。
注意:flex-grow
和flex-shrink
的这些值是比例。通常,如果我们将所有项目的设置为flex: 1 1 200px
,然后希望一个项目以两倍的速度增长,我们将把该项目设置为flex: 2 1 200px
。但是,如果您愿意,也可以使用flex: 10 1 200px
和flex: 20 1 200px
。
flex属性的简写值
您很少会看到flex-grow
、flex-shrink
和flex-basis
属性单独使用;相反,它们被组合到flex
简写中。flex
简写允许您按此顺序设置三个值 - flex-grow
、flex-shrink
、flex-basis
。
下面的实时示例允许您测试flex
简写的不同值;请记住,第一个值是flex-grow
。赋予它一个正值意味着该项目可以增长。第二个是flex-shrink
- 具有正值,项目可以缩小,但前提是它们的总值溢出了主轴。最后一个值是flex-basis
;这是项目用作其基本值以增长和缩小的值。
还有一些预定义的简写值涵盖了大多数用例。您经常会在教程中看到这些值,并且在许多情况下,这些值是您唯一需要使用的。预定义的值如下
flex: initial
flex: auto
flex: none
flex: <positive-number>
initial
值是CSS全局值,它表示属性的初始值。设置flex: initial
会将项目重置为三个详细属性的初始值,这与flex: 0 1 auto
相同。flex-grow
的初始值为0
,因此项目不会增长到超过其flex-basis
大小。flex-shrink
的初始值为1
,因此项目如果需要可以收缩,而不是溢出。flex-basis
的初始值为auto
。项目将使用在主尺寸上为项目设置的任何大小,或者它们将从内容大小获取其大小。
使用flex: auto
与使用flex: 1 1 auto
效果相同;这类似于flex: initial
,区别在于项目可以增长并填充容器,并在需要时收缩。
使用flex: none
将创建完全不可伸缩的弹性项目。这就像你写了flex: 0 0 auto
一样。项目不能增长或收缩,并且将使用弹性盒布局和flex-basis
值为auto
进行排列。
你在教程中经常看到的简写是flex: 1
或flex: 2
等等。这分别等同于写flex: 1 1 0
或flex: 2 1 0
。项目可以从flex-basis
值为0
开始增长和收缩。
在下面的实时示例中尝试这些简写值。
项目之间的对齐、对齐方式和空闲空间分配
弹性盒的一个关键特性是能够在主轴和交叉轴上对齐和对正项目,以及在弹性项目之间分配空间。请注意,这些属性设置在弹性容器上,而不是在项目本身上。
align-items
align-items
属性在交叉轴上对齐所有弹性项目。
此属性的初始值为stretch
,这也是弹性项目默认情况下会拉伸到弹性容器高度的原因(如果flex-direction
设置为column
或column-reverse
,则为宽度)。此高度可能来自容器中最高的项目,也可能来自弹性容器本身设置的大小。
你可以将align-items
设置为flex-start
或简写为start
,以使项目在弹性容器的起始处对齐,设置为flex-end
或简写为end
,以将其对齐到末尾,或设置为center
以将其对齐到中心。在实时示例中尝试一下——我已经为弹性容器设置了一个高度,以便你可以看到项目如何在容器内移动。看看如果你将align-items
的值设置为以下值会发生什么情况:
stretch
flex-start
flex-end
start
end
center
baseline
last baseline
align-items
设置在弹性容器上,并影响所有弹性项目。如果你想将某个弹性项目与其他项目对齐方式不同,可以在弹性项目上设置align-self
。
justify-content
justify-content
属性用于在主轴上对齐项目,即flex-direction
设置流的方向。初始值为flex-start
,它将项目在容器的起始边缘对齐,但你也可以将其值设置为flex-end
以将其对齐到末尾,或设置为center
以将其对齐到中心。
你还可以使用space-between
值来获取项目布局后所有剩余的空间,并在项目之间平均分配这些空间,这样每个项目之间都会有相等的空间。要使每个项目的右侧和左侧(或列的顶部和底部)有相等的空间,请使用space-around
值。使用space-around
,项目两端会有一个半尺寸的空间。或者,要使项目周围有相等的空间,请使用space-evenly
值。使用space-evenly
,项目两端会有一个全尺寸的空间。
在实时示例中尝试以下justify-content
值:
start
end
left
right
normal
flex-start
flex-end
center
space-around
space-between
space-evenly
stretch
文章Aligning items in a flex container
更深入地探讨了这些属性,以便更好地理解它们的工作原理。但是,这些基本示例在大多数用例中都很有用。
justify-items
justify-items
属性在弹性盒布局中被忽略。
place-items 和 place-content
place-items
属性是align-items
和justify-items
的简写属性。如果设置在弹性容器上,它将设置对齐方式但不设置对正方式,并且justify-items
在弹性盒中被忽略。
还有一个简写属性place-content
,它定义了align-content
和justify-content
属性。align-content
属性仅影响换行的弹性容器,并在Aligning items in a flex container
中进行了讨论。
后续步骤
阅读本文后,你应该了解弹性盒的基本功能。在下一篇文章中,我们将了解此规范与 CSS 的其他部分的关系
。