在经过长达10年的发展之后,CSS3终于迎来了一个简单而强大的布局属性——flex。Flex布局,又称弹性布局,通过使用flexbox属性使容器具有弹性,能够自动适应各种设备的不同宽度,摆脱了对传统块状布局和浮动定位的依赖。
🔢什么是Flex布局?
Flex布局通过flexbox属性让容器具有弹性,这使得容器内的子元素可以自动调整大小和位置。相对于以前的布局方式,Flex布局更为简单直观,而且适应性更强。
考虑一个简单的例子,如果我们想要实现一个左侧定宽,右侧自适应的导航布局,使用传统的float布局,代码可能是这样的:
这种方式需要理解float的概念,同时还需要处理文档流、盒子模型、display等属性,增加了学习成本。
相比之下,使用flex布局则简单得多,只需要设置一个伸缩系数即可。下面是使用flex布局的代码:
在上述代码中,只需要将父级容器设置为flex形式(display: flex),然后在需要自动伸缩的容器里设置相应属性即可。例如,flex: 1表示占据所有其他行所剩的空间,实现了简单而灵活的弹性布局。
除了在响应式布局方面非常方便之外,flex在对齐等方面更加便捷,大大降低了学习成本,提高了工作效率。因此,让我们一同拥抱未来的布局方式,告别繁琐的float,迎接灵活高效的flex布局!
👉在 Flex 布局中,存在几个关键的核心概念,分别是:主轴与交叉轴、起始线和终止线、Flex 容器与 Flex 容器项。
♐主轴和交叉轴
在 Flex 布局中,主轴和交叉轴的方向由 flex-direction 属性决定,该属性可取四个值:
row
row-reverse
column
column-reverse
如果选择 row 或 row-reverse,主轴(Main Axis)将是横向的 X 轴,而交叉轴(Cross Axis)则是竖向的 Y 轴。
如果选择 column 或 column-reverse,主轴将变成竖向的 Y 轴,而交叉轴则是横向的 X 轴。
🐠起始线和终止线
过去,CSS 的书写模式通常被默认为水平的,即从左到右。然而,现代布局方式已经考虑到了不同的书写模式,不再假设一行文字总是从文档的左上角向右书写。
对于不同的语言,其书写方向各异,例如英文是从左到右,而阿拉伯文则是从右到左。因此,对于这两种语言,主轴和交叉轴的起始线和终止线可能存在差异。以下是一个简单的例子,假设 flex-direction 是 row,并且我们使用英文书写。由于英文是从左到右书写的,主轴的起始线将位于左侧,而终止线则在右侧,如下图所示。
然而,如果我们切换到阿拉伯文书写,由于阿拉伯文是从右到左书写的,主轴的起始线就变成了右侧,终止线则在左侧,如下图所示。
在 Flex 布局中,起始线和终止线的设定决定了 Flex 容器中的 Flex 元素从哪个方向开始排列。例如,通过设置 direction: ltr 将文字书写方向设置为从左到右时,起始线在左侧,终止线在右侧。此时,如果 flex-direction 的值是 row,Flex 元素将从左到右开始排列。但如果 flex-direction 的值是 row-reverse,Flex 元素将从右到左开始排列。
在上述例子中,交叉轴的起始线是 flex 容器的顶部,而终止线则是底部,因为这两种语言都采用水平书写模式。但如果有一种语言的书写形式是从底部到顶部,那么当将 flex-direction 设置为 column 或 column-reverse 时,也会出现类似的变化。
🍧Flex 容器与 Flex 元素
一旦我们将容器的 display 属性值改为 flex 或 inline-flex,这个容器就会成为 Flex 容器,而该容器中的直系子元素将变为 Flex 元素。如下所示,parent 元素成为 Flex 容器,而 son 元素成为 Flex 元素。
在这个例子中,parent 元素通过设置 display: flex; 成为了一个 Flex 容器,从而使其直系子元素 son 成为了 Flex 元素。Flex 容器提供了一种弹性布局方式,允许子元素根据需要自动调整其尺寸和位置。 Flex 元素则是 Flex 容器中直接子元素,参与弹性布局的调整。
🌈Flex 布局核心属性
在使用 Flex 布局时,尽管有众多属性可供利用,但其中几项被认为是核心属性。以下是其中的几个关键属性:
flex-direction: 主轴方向
flex: 伸缩系数及初始值
justify-content: 主轴方向对齐
align-items: 交叉轴方向对齐
这些属性对于控制 Flex 布局的方向、伸缩、对齐等方面起着关键的作用。如果想深入了解更多有关 Flex 属性的信息,可以参考 Mozilla 开发者网络(MDN)的flex 布局基本概念。
🔄flex-direction:定义主轴方向
如前文所述,flex-direction 用于定义主轴的方向,可选取以下 4 个值:
row 默认值
row-reverse
column
column-reverse
一旦主轴确定,交叉轴也随之确定。主轴和交叉轴的关系将影响后续对齐属性的表现,因此理解它们的关系至关重要!以下是一个简单的例子,展示了如何通过代码实现不同的展示效果:
上述代码将呈现如下图所示的效果:
如果你将 flex-direction 更改为 column-reverse,则会得到以下效果:
通过调整 flex-direction 的值,可以轻松实现不同的主轴方向,从而灵活控制布局的排列方式。
🤏flex 伸缩系数及初始值
如前所述,Flex 布局支持响应式布局,其核心在于使用 flex 属性,实际上是 flex-grow、flex-shrink 和 flex-basis 这三个参数的缩写形式,具体如下所示:
在深入了解这些属性的作用之前,我们需要先理解“可用空间”(available space)的概念。这几个 flex 属性实际上是在改变了 Flex 容器中可用空间的分配行为。
假设有一个容器宽度为 500px,内部有三个宽度为 100px 的元素,那么这三个元素需要占用 300px 的宽度,剩下的 200px 就是可用空间。默认情况下,flexbox 会将这 200px 的空间留在最后一个元素的后面。
如果我们希望这些元素能够自动扩展以填充剩余空间,就需要控制可用空间在这些元素之间的分配方式,这正是这些元素上的 flex 属性所要做的事情。
🐷flex-basis 属性
flex-basis 属性用于定义 Flex 元素的尺寸,默认值为 auto。在这种情况下,浏览器会检查元素是否具有确定的尺寸。如果有确定的尺寸,则使用该尺寸作为 Flex 元素的尺寸;否则,将采用元素内容的尺寸。
🐖flex-grow
当 flex-grow 被设置为正整数时,Flex 元素将以 flex-basis 为基准,沿主轴方向增长尺寸。这使得元素能够扩展并占据主轴方向上的可用空间。如果其他元素也允许扩展,它们将分别占用可用空间的一部分。
例如,在有三个 Flex 元素(a、b、c)的容器中,如果我们将所有元素的 flex-grow 值设置为 1,容器的可用空间将被这些元素平均分配。它们将会扩展以填充容器主轴方向上的空间。
然而,有时我们可能需要按比例划分剩余空间。例如,如果第一个元素的 flex-grow 值为 2,而其他元素的值为 1,则第一个元素将占用 2/4(在这个例子中即为 200px 中的 100px),而其他两个元素将各自占用 1/4(各 50px)。
🐏flex-shrink
与 flex-grow 属性处理 Flex 元素在主轴上增加空间的问题类似,flex-shrink 属性处理 Flex 元素在收缩方面的问题。如果容器中没有足够的空间来排列 Flex 元素,可以将 flex-shrink 属性设置为正整数,从而使其在 flex-basis 以下收缩。
与 flex-grow 属性类似,可以为 flex-shrink 属性分配不同的值以控制 Flex 元素的收缩程度。给 flex-shrink 属性赋予较大的数值会使同级元素相对于较小数值的元素更大程度地收缩。
🥂justify-content 主轴方向对齐
justify-content 属性用于在主轴方向上对齐元素,其初始值为 flex-start,即元素从容器的起始线开始排列。justify-content 属性具有以下 5 个不同的值:
flex-start:从起始线开始排列,为默认值。
flex-end:从终止线开始排列。
center:在中间排列。
space-around:每个元素的左右空间相等。
space-between:将元素排列好后,将剩余的空间平均分配到元素之间。
不同对齐方式的效果如下:
flex-start:
flex-end:
center:
space-around:
space-between:
🍉align-items 交叉轴方向对齐
align-items 属性用于在交叉轴方向上对齐元素,其初始值为 stretch,即拉伸到最高元素的高度。align-items 属性具有以下 5 个不同的值:
stretch:拉伸到最高元素的高度,为默认值。
flex-start:按 flex 容器起始位置对齐。
flex-end:按 flex 容器结束位置对齐。
center:居中对齐。
baseline:始终按文字基线对齐。
不同对齐方式的效果如下:
stretch:
flex-start:
flex-end:
center:
需要注意的是,无论是 align-items 还是 justify-content,它们都是以主轴或者交叉轴为参考,而不是横向和竖向为参考。理解这一点至关重要。
🌰Flex 默认属性
在没有设置任何自定义值时,flex 容器中的所有 flex 元素都会表现出以下默认行为:
元素排列为一行(flex-direction 属性的初始值是 row)。
元素从主轴的起始线开始排列。
元素不会在主维度方向拉伸,但可以缩小。
元素被拉伸以填充交叉轴的大小。
flex-basis 属性为 auto。
flex-wrap 属性为 nowrap。
理解 Flex 元素的默认值对于更好地进行布局排版非常有帮助。
🔒实战项目拆解
在学习了众多的 Flex 布局知识点后,可能你会觉得有些干巴巴的。让我们来看看实际项目中是如何运用 Flex 布局的。
我在 CodePen 上找到了一个案例,该布局是通过 Flex 布局实现的。通过简单的分析,我们可以将其拆解成以下 Flex 布局结构,如下图所示。
首先,整体分为两大部分,即导航栏和内容区域。这部分是纵向排列的(flex-direction: column),如上图中的红框部分。然后,在内容区域,将其再次分成左侧导航栏和右侧内容区域,这一块是横向排列的(flex-direction: row),如上图中的蓝框部分。
剩余的内容布局类似,实际上就是不断套用 Flex 布局。由于篇幅有限,这里不再深入拆解,总体的布局思路已经清晰了。
虽然使用了 Flex 布局,布局看起来变得简单了很多。但理论只是纸上谈兵,真正的理解还需要动手实践,否则只是空谈而已。
🍚总结
到这里,关于 Flex 布局的核心知识点基本上已经介绍完毕。熟悉这几个核心知识点,你基本可以开始实践并练习,很可能不会遇到太大的问题。至于一些较为小众的属性,可以在需要用到时再去查阅文档。
在接下来的学习中,更多的时间应该投入到找一些实际的案例进行练习,因为只有实践才能真正巩固所学知识。我也计划在以后分享一些我在 Flex 布局方面的项目实践经验,希望对大家有所帮助。