×

CSS Flex 布局 一维 自由排列 技巧

深度解析 Flex 布局,轻松掌握一维自由排列技巧!

元智汇电子 元智汇电子 发表于2023-12-09 13:57:34 浏览346 评论0

抢沙发发表评论

📔1. Flexbox 简介

Flexbox,即 Flexible Box Module,是一种一维布局模型,旨在提供项目间空间分配和强大对齐能力。与 CSS Grid Layout 的二维模型相对应,Flexbox 更专注于一次处理一维布局,可以是行或列。传统布局方案(基于盒状模型、display 属性 + position 属性 + float 属性)在特殊布局下效率不高,而 Flexbox 提供了一种更便捷、灵活的方式,使容器中的项目可以轻松布置、对齐和分配空间。

Flexbox 主要思想是通过使容器能够改变项目的宽度/高度和顺序,更好地填充可用空间,适应各种显示设备和屏幕尺寸。灵活的容器可以扩展或收缩项目,以便更好地利用空间。

相对于常规布局,Flexbox 布局不受方向限制,既适用于小组件也适用于小规模布局。与之相比,传统布局在方向改变、大小调整、拉伸和缩小等方面显得较为僵硬。值得注意的是,Flexbox 更适合应用程序组件和小规模布局,而对于大规模布局,网格布局更为合适。


📔2. Flexbox 的主要概念

Flexbox 布局基于 "弹性流动方向",其中主要概念包括:

  • 主轴(main axis): 弹性容器的主要流动方向。

  • main-start | main-end: 弹性项目在容器主轴方向上从 main-start 开始到 main-end 进行排列。

  • 主尺寸(main size): 弹性项目的宽度或高度,以主要尺寸中的那个为准。

  • 交叉轴(cross axis): 垂直于主轴的轴,方向取决于主轴的方向。

  • cross-start | cross-end: 弹性项目在容器的交叉轴方向上从 cross-start 开始到 cross-end 进行排列。

  • 交叉尺寸(cross size): 交叉轴的宽度或高度。


🚀3. 浏览器支持

Flexbox 在主流浏览器中得到了广泛支持,可在 Caniuse 网站上查看详细支持情况。几乎所有现代浏览器都能很好地兼容 Flexbox,为开发者提供了强大的布局工具。

image.png

深入了解 Flex 布局,将为你的前端开发提供更多灵活性和便捷性。


🥂2、Flex 容器(Container)属性

🍉2.1 display

要创建 Flex 布局容器,可以使用 display 属性,并将其值设置为 flex 或 inline-flex。

image.png

🍉2.2 flex-direction

flex-direction 用于定义弹性容器中主轴的方向。Flexbox 是单向布局,可选择水平行布局或垂直列布局。

image.png

  • row(默认): 主轴为水平方向,从左至右排列。

  • row-reverse: 主轴为水平方向,从右至左排列。

  • column: 主轴为垂直方向,从上至下排列。

  • column-reverse: 主轴为垂直方向,从下至上排列。

在 Flex 布局中,主轴和交叉轴是两个关键概念。主轴是子元素排列的方向,而交叉轴是垂直于主轴的方向。例如,如果设置了 flex-direction: row,主轴就是水平方向,而交叉轴就是垂直方向。通过不同的属性,可以控制子元素在主轴和交叉轴上的对齐方式,如 justify-content 控制主轴对齐,align-items 控制交叉轴对齐。


🍉2.3 flex-wrap

默认情况下,弹性项目会尝试将所有项目放在一行中。flex-wrap 用于设置是否换行,可取值为 nowrap(不换行)、wrap(换行) 或 wrap-reverse(反向换行)。

image.png

  • nowrap(默认):所有弹性项目都在一行上,可能导致容器溢出。

  • wrap: 弹性项目将换行到多行,从上到下,方向由 flex-direction 定义。

  • wrap-reverse: 弹性项目将从下到上换行到多行,与 flex-direction 定义的方向相反。

下面是一个演示,帮助感受这三个属性值的区别:

image.png

发现 wrap 和 wrap-reverse 实际上是镜像的,只需记住 wrap 如何换行,就能理解 wrap-reverse 如何换行。

🍉2.4 flex-flow

flex-flow 是 flex-direction 和 flex-wrap 两个属性的简写,默认值是 row nowrap。

image.png

🍉2.5 justify-content

justify-content 用于定义主轴上子元素的对齐方式。

image.png

对齐方式包括:

  • flex-start(默认):从行首开始排列,每行第一个元素与行首对齐,后续元素与前一个对齐。

  • flex-end:从行尾开始排列,每行最后一个元素与行尾对齐,其他元素与后一个对齐。

  • start:从行首开始排列,每行第一个元素与行首对齐,后续元素与前一个对齐。

  • end:从行尾开始排列,每行第一个元素与行尾对齐,后续元素与前一个对齐。

  • left:元素一个挨一个在容器的左边缘对齐,如果属性轴与内联轴不平行,则行为类似于start。

  • right:元素以容器右边缘为基准,一个挨着一个对齐,如果属性轴与内联轴不平行,则行为类似于end。

  • center:元素向每行中点排列,每行第一个元素到行首的距离与最后一个元素到行尾的距离相同。

  • space-between:在每行上均匀分配元素,相邻元素间距离相同,首尾元素分别与行首和行尾对齐。

  • space-around:在每行上均匀分配元素,相邻元素间距离相同,首尾元素与行首和行尾的距离是相邻元素间距离的一半。

  • space-evenly:元素沿主轴均匀分布,包括起始和结束位置。

  • baseline / first baseline / last baseline:基于基线对齐元素,可指定第一或最后基线对齐。

  • stretch:如果元素总和尺寸小于容器尺寸,自动尺寸的元素将被均匀增加,仍受到限制。

  • safe:与对齐关键字一起使用,确保元素不会溢出容器,避免数据丢失。

  • unsafe:无论元素和容器大小如何,都使用给定的对齐值。

请注意,不同浏览器对这些值的支持可能有差异,主流浏览器通常支持 flex-start、flex-end 和 center。 Safe 和 unsafe 可用于确保元素不会溢出容器,防止数据丢失。

🍉2.6 align-items

align-items 用于定义交叉轴上子元素的对齐方式。

image.png

对齐方式包括:

  • stretch(默认):弹性项的交叉轴尺寸被拉伸至与行高相同。

  • flex-start / start / self-start:元素向交叉轴起点对齐。

  • flex-end / end / self-end:元素向交叉轴终点对齐。

  • center:元素在交叉轴上居中,如果元素高度大于容器,则在两个方向上溢出距离相同。

  • baseline / first baseline / last baseline:所有元素向基线对齐,以第一或最后基线为参考。

  • safe center / unsafe center:与对齐关键字一起使用,确保安全或不安全地居中对齐。

🍉2.7 align-content

align-content 用于定义多根轴线的对齐方式,其值与 justify-content 相同,但仅在存在多行轴线时生效。

注意:该属性仅对多行 flex 容器有效,其中 flex-wrap 设置为 wrap 或 wrap-reverse。对于单行 flex 容器(即 flex-wrap 设置为其默认值 no-wrap),align-content 不会生效。

image.png

对齐方式包括:

  • flex-start:所有行从交叉轴起点开始填充。

  • flex-end:所有行从交叉轴末尾开始填充。

  • start:所有行从容器的交叉轴起始边缘开始填充。

  • end:所有行从容器的交叉轴结束边缘开始填充。

  • center:所有行朝向容器的中心填充。

  • space-between:所有行在容器中平均分布。

  • space-around:所有行在容器中平均分布,相邻两行间距相等。

  • space-evenly:所有行沿交叉轴均匀分布在对齐容器内。

  • stretch:拉伸所有行以填满剩余空间。

同时,safe 和 unsafe 可以与对齐关键字一起使用,确保安全或不安全地对齐项。

🍉2.8 gap, row-gap, column-gap

gap 属性是 row-gap 和 column-gap 的简写,用于指定网格、flex 和多列布局中行和列之间的空间,也称为 gutters。

该属性明确控制弹性项目之间的间距,仅适用于不在容器外边缘的项目之间。

image.png

上述代码中,gap 可以设置为一个值,表示行和列之间的间距相同。也可以分别使用两个值,分别表示 row-gap 和 column-gap 的大小。

以下是一个示例:

image.png

通过这些属性,可以更灵活地控制弹性项目之间的空间,适用于各种布局需求。

🍉3.1 order

order 属性用于定义子元素的排列顺序,可以取任意整数,默认为 0。数值越小,项目越靠前。默认情况下,弹性项目按照源代码顺序排列,但是 order 属性允许控制它们在 flex 容器中的出现顺序。

image.png

相同的项目使用相同的 order 值可以恢复到源代码顺序。

🍉3.2 flex-grow

flex-grow 用于设置项目在 flex 容器中分配剩余空间的相对比例,默认为 0,表示即使存在剩余空间也不放大。

剩余空间是 flex 容器的大小减去所有 flex 项的大小之和。如果所有项目的 flex-grow 设置为 1,则容器中的剩余空间将平均分配给所有项目。如果其中一个项目的值为 2,则该项目将占用其他项目的两倍空间(或者至少会尝试)。

image.png

请注意,设置为负数是无效的。通常,flex-grow 与其他 flex 属性(flex-shrink 和 flex-basis)一起使用,可以使用 flex 属性进行简写,以确保所有值都被设置。

🍉3.3 flex-shrink

flex-shrink 属性指定了 flex 元素的收缩规则。只有在默认宽度之和大于容器时,项目才会发生收缩,其收缩的大小依据 flex-shrink 的值。默认为 1,即如果空间不足,项目会自动缩小。

image.png

请注意,设置为负数是无效的。

通过这些属性,可以更灵活地控制项目的布局和尺寸。

🍉3.4 flex-basis

flex-basis 属性用于指定 flex 元素在主轴方向上的初始大小。如果未使用 box-sizing 更改盒模型,该属性将决定 flex 元素的内容盒(content-box)的尺寸。默认值为 auto,即根据内容自适应。

备注:flex-basis 简史

最初,"flex-basis:auto" 的含义是 "参照我的 width 和 height 属性"。后来,"flex-basis:auto" 的含义变为自动尺寸,而 "main-size" 变为 "参照我的 width 和 height 属性"。然而,这个更改后来在 bug 1093316 中被撤销,因此 "auto" 又恢复了原来的含义,而一个新的关键字 'content' 变为自动尺寸(bug 1105111 包括了增加这个关键字)。

image.png

备注:当元素同时设置了 flex-basis(除值为 auto 外)和 width(或在 flex-direction: column 情况下设置了 height),flex-basis 具有更高的优先级。

🍉3.5 flex

flex 是 flex-grow、flex-shrink 和 flex-basis 的简写形式,默认值为 0 1 auto。第二个和第三个参数(flex-shrink 和 flex-basis)是可选的。

flex 属性的默认值为 0 1 auto,但如果将其设置为单个数值,例如 flex: 5;,则会将 flex-basis 更改为 0%,因此等效于设置 flex-grow: 5; flex-shrink: 1; flex-basis: 0%;。

image.png

通过这些属性,可以更灵活地定义 flex 元素在主轴上的布局和尺寸。

🍉3.6 align-self

align-self 用于对齐当前 flex 容器中的元素,可以覆盖已有的 align-items 的值。在网格中,它使项目在网格区域内对齐。而在 Flexbox 中,按照交叉轴(当前 flex 元素排列方向的垂直方向)进行排列。

image.png

通过这些值,可以在特定元素上定义其在交叉轴上的对齐方式,独立于容器的整体设置。请注意,float、clear 和 vertical-align 对弹性项目没有影响。

以下是一个示例演示了 align-self 的不同值的效果:

image.png


🔒4、Flex 布局和 Grid 布局之间的不同之处

Flexbox 和 Grid 在前端布局中都是强大的工具,它们具有许多相似之处,但也存在一些关键的区别。以下是它们之间的一些不同之处:

🍚4.1 Flexbox 可以选择性地换行

在 Flexbox 中,我们可以选择允许容器中的项目换行。当一行的项目填满时,它们会自动换行到下一行。这样的布局可能导致项目在新行中的排列与前一行不同,呈现出砖石结构的外观。

与之不同,Grid 也可以选择换行,但是它更注重于二维布局。项目可以填充一行并移动到新行,但它们在换行时会沿着相同的网格线排列,以创建更为一致的布局。

🍚4.2 Flex 是一维布局,而 Grid 是二维布局

Flexbox 是一种一维布局,因为它主要沿着主轴排列元素,可以选择允许换行以创建类似行和列的效果。然而,由于元素仅沿单一轴排列,无法以声明方式控制元素在布局中的最终位置。

相比之下,Grid 是一种更强大的二维布局。在 Grid 中,我们可以明确地定义行和列的大小,并根据这些选择将内容放置在相应的网格单元中。这种二维性使得 Grid 在布局上更加灵活,可以更精准地控制元素的位置。

在 Flexbox 中,大部分布局设置发生在子元素上,而在 Grid 中,主要的布局定义发生在父元素上。

以下是对 Flexbox 和 Grid 在布局中的应用的简化示例:

image.png

image.png

🍚4.3 Grid 更擅长重叠

在 flexbox 中,要实现元素的重叠通常需要依赖传统的方法,如负边距、transforms 或绝对定位,以打破 flex 容器的行为。而在使用网格时,我们可以直接将项目放置在重叠的网格线上,甚至可以将它们放置在完全相同的网格单元格中。

下面是一个演示:

image.png

🍚4.4 Grid 更稳固

尽管 flexbox 的灵活性在某些情况下是优势,但是单个 flex 项目的尺寸是相当复杂的。它涉及到 width、min-width、max-width、flex-basis、flex-grow 和 flex-shrink 的组合,还包括内容和间距等因素,以及同一行中其他项目的影响。相比之下,网格具有更明确的空间占用概念,可以使用小数单位,并且更容易处理项目的位置,因为我们是直接在网格中设置线,并将项目放置在指定的位置。

🍚4.5 Flex 可以把东西推开

Flexbox 具有一个相当独特的特性,例如,可以通过在一个元素上设置 margin-right: auto; 来推开其他元素,如果有足够的空间,该元素会推动其他元素尽可能远。

🍚4.6 用 Flex 还是 Grid ?

有一位推特大佬总结得很到位:

"Flexbox 用于对齐。CSS Grid 用于布局。"

这意味着当你已经有了明确的布局结构时,使用 Grid 布局更为适合,而当你只是想要确保所有元素都适应空间时,使用 Flex 布局更为合适。在选择使用 Flex 还是 Grid 时,布局的优先级与内容的优先级有关。


📱5、以下推荐2个可视化学习 Flexbox 布局的站点




群贤毕至

访客