别再用 float 布局了,flex 才是未来!

2023年 10月 26日 78.5k 0

前面一篇文章「一文带你弄懂 CSS 布局知识」里,我整体介绍了 CSS 的布局知识,其中说到 float 布局是 CSS 不断完善的副产物。而在 2023 年的今天,flex 这种布局方式才是未来!那么今天我们就来学习下 flex 弹性布局。

什么是 Flex 布局?

在经过了长达 10 年的发展之后,CSS3 才终于迎来了一个简单好用的布局属性 —— flex。Flex 布局又称弹性布局,它使用 flexbox 属性使得容器有了弹性,可以自动适配各种设备的不同宽度,而不必依赖于传统的块状布局和浮动定位。

举个很简单地例子,如果我们想要实现一个很简单左侧定宽,右侧自适应的导航布局,如下图所示。

-w1239-w1239

在没有 flex 之前,我们的代码是这么写的。


4.1 两栏布局 - 左侧定宽、右侧自适应 - float

  
  

/** 4.1 两栏布局 - 左侧定宽、右侧自适应 - float **/
.left41 {
  float: left;
  width: 300px;
  height: 500px;
  background-color: pink;
}
.right41 {
  width: 100%;
  height: 500px;
  background-color: aquamarine;
}

这种方式不好的地方在于,我们还需要去理解 float 这个概念。一旦需要理解 float 这个概念,我们就会拖出一大堆概念,例如文档流、盒子模型、display 等属性(虽然这些东西确实应该学)。但对于 flex 来说,它就很简单,只需要设置一个伸缩系数即可,如下代码所示。


4.2 两栏布局 - 左侧定宽、右侧自适应 - flex

  
  

.container42 {
  display: flex;
}
.left42 {
  width: 300px;
  height: 500px;
  background-color: pink;
}
.right42 {
  flex: 1;
  width: 100%;
  height: 500px;
  background-color: aquamarine;
}

上面的代码里,我们只需要将父级容器设置为 flex 展示形式(display: flex),随后在需要自动伸缩的容器里设置属性即可。上面代码中的 flex: 1 表示其占据所有当行所剩的空间。通过这样的方式,我们非常方便地实现了弹性布局。

当然,上面只是一个最简单的例子,甚至还不是很能体现出 flex 的价值。flex 除了在响应式布局方面非常方便之外,它在对齐等方面更加方便,能够极大地降低学习成本、提高工作效率。

Flex 核心概念

对于 Flex 布局来说,其有几个核心概念,分别是:主轴与交叉轴、起始线和终止线、Flex 容器与 Flex 容器项。

主轴和交叉轴

在 Flex 布局中有一个名为 flex-direction 的属性,可以取 4 个值,分别是:

  • row
  • row-reverse
  • column
  • column-reverse

如果你选择了 row 或者 row-reverse,那么主轴(Main Axis)就是横向的 X 轴,交叉轴(Cross Axis)就是竖向的 Y 轴,如下图所示。

主轴是横向的X轴,交叉轴是竖向的Y轴主轴是横向的X轴,交叉轴是竖向的Y轴

如果你选择了 column 或者 column-reverse,那么主轴(Main Axis)就变成是竖向的 Y 轴,交叉轴(Cross Axis)就是横向的 X 轴,如下图所示。

主轴是竖向的Y轴,交叉轴是横向的X轴主轴是竖向的Y轴,交叉轴是横向的X轴

起始线和终止线

过去,CSS 的书写模式主要被认为是水平的,从左到右的。但现代的布局方式涵盖了书写模式的范围,所以我们不再假设一行文字是从文档的左上角开始向右书写的。

对于不同的语言来说,其书写方向不同,例如英文是从左到右,但阿拉伯文则是从右到左。那么对于这两种语言来说,其xx会有所不同 TODO。举个简单的例子,如果 flex-direction 是 row ,并且我是在书写英文。由于英文是从左到右书写的,那么主轴的起始线是左边,终止线是右边,如下图所示。

-w557-w557

但如果我在书写阿拉伯文,由于阿拉伯文是从右到左的,那么主轴的起始线是右边,终止线是左边,如下图所示。

-w541-w541

在 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 核心属性

对于 Flex 来说,它有非常多的用法,但核心属性却相对较少。这里我只简单介绍几个核心属性,如果你想了解更多 Flex 的属性,可以去 Mozilla 官网查询,这里给个传送门:flex 布局的基本概念 - CSS:层叠样式表 | MDN。

对于 Flex 布局来说,其核心属性有如下几个:

  • flex-direction 主轴方向
  • flex 伸缩系数及初始值
  • justify-content 主轴方向对齐
  • align-items 交叉轴方向对齐
  • flex-direction 主轴方向

    如上文所介绍过的,flex-direction 定义了主轴的方向,可以取 4 个值,分别是:

    • row 默认值
    • row-reverse
    • column
    • column-reverse

    一旦主轴确定了,交叉轴也确定了。主轴和交叉轴与后续的对齐属性有关,因此弄懂它们非常重要!举个很简单的例子,如下的代码将展示下图的展示效果。

    .box {
      display: flex;
      flex-direction: row-reverse;
    }
    
    
      One
      Two
      Three
    

    -w538-w538

    如果你将 flex-direction 改成 column-reverse,那么将会变成如下的效果,如下图所示。

    -w541-w541

    flex 伸缩系数及初始值

    前面说到 Flex 布局可以很方便地进行响应式布局,其实就是通过 flex 属性来实现的。flex 属性其实是 flex-grow、flex-shrink、flex-basis 这三个参数的缩写形式,如下代码所示。

    flex-grow: 1;
    flex-shrink: 1;
    flex-basis: 200px;
    /* 上面的设置等价于下面 flex 属性的设置 */
    flex: 1 1 200px;

    在考虑这几个属性的作用之前,需要先了解一下 可用空间 available space 这个概念。这几个 flex 属性的作用其实就是改变了 flex 容器中的可用空间的行为。

    假设在 1 个 500px 的容器中,我们有 3 个 100px 宽的元素,那么这 3 个元素需要占 300px 的宽,剩下 200px 的可用空间。在默认情况下,flexbox 的行为会把这 200px 的空间留在最后一个元素的后面。

    -w537-w537

    如果期望这些元素能自动地扩展去填充满剩下的空间,那么我们需要去控制可用空间在这几个元素间如何分配,这就是元素上的那些 flex 属性要做的事。

    flex-basis

    flex-basis 属性用于设置 Flex 元素的大小,其默认值是 auto。此时浏览器会检查元素是否有确定的尺寸,如果有确定的尺寸则用该尺寸作为 Flex 元素的尺寸,否则就采用元素内容的尺寸。

    flex-grow

    flex-grow 若被赋值为一个正整数,flex 元素会以 flex-basis 为基础,沿主轴方向增长尺寸。这会使该元素延展,并占据此方向轴上的可用空间(available space)。如果有其他元素也被允许延展,那么他们会各自占据可用空间的一部分。

    举个例子,上面的例子中有 a、b、c 个 Flex 元素。如果我们给上例中的所有元素设定 flex-grow 值为 1,容器中的可用空间会被这些元素平分。它们会延展以填满容器主轴方向上的空间。

    但很多时候,我们可能都需要按照比例来划分剩余的空间。此时如果第一个元素 flex-grow 值为 2,其他元素值为 1,则第一个元素将占有 2/4(上例中,即为 200px 中的 100px), 另外两个元素各占有 1/4(各 50px)。

    flex-shrink

    flex-grow 属性是处理 flex 元素在主轴上增加空间的问题,相反 flex-shrink 属性是处理 flex 元素收缩的问题。如果我们的容器中没有足够排列 flex 元素的空间,那么可以把 flex 元素 flex-shrink 属性设置为正整数,以此来缩小它所占空间到 flex-basis 以下。

    与flex-grow属性一样,可以赋予不同的值来控制 flex 元素收缩的程度 —— 给flex-shrink属性赋予更大的数值可以比赋予小数值的同级元素收缩程度更大。

    justify-content 主轴方向对齐

    justify-content 属性用来使元素在主轴方向上对齐,它的初始值是 flex-start,即元素从容器的起始线排列。justify-content 属性有如下 5 个不同的值:

    • flex-start:从起始线开始排列,默认值。
    • flex-end::从终止线开始排列。
    • center:在中间排列。
    • space-around:每个元素左右空间相等。
    • space-between:把元素排列好之后,剩余的空间平均分配到元素之间。

    各个不同的对齐方式的效果如下图所示。

    flex-start:

    -w454-w454

    flex-end:

    -w444-w444

    center:

    -w449-w449

    space-around:

    -w442-w442

    space-between:

    -w453-w453

    align-items 交叉轴方向对齐

    align-items 属性可以使元素在交叉轴方向对齐,它的初始值是 stretch,即拉伸到最高元素的高度。align-items 属性有如下 5 个不同的值:

    • stretch:拉伸到最高元素的高度,默认值。
    • flex-start:按 flex 容器起始位置对齐。
    • flex-end:按 flex 容器结束为止对齐。
    • center:居中对齐。
    • baseline:始终按文字基线对齐。

    各个不同的对齐方式的效果如下图所示。

    stretch:

    -w448-w448

    flex-start:

    -w439-w439

    flex-end:

    -w438-w438

    center:

    -w444-w444

    要注意的事,无论 align-items 还是 justify-content,它们都是以主轴或者交叉轴为参考的,而不是横向和竖向为参考的,明白这点很重要。

    Flex 默认属性

    由于所有 CSS 属性都会有一个初始值,所以当没有设置任何默认值时,flex 容器中的所有 flex 元素都会有下列行为:

    • 元素排列为一行 (flex-direction 属性的初始值是 row)。
    • 元素从主轴的起始线开始。
    • 元素不会在主维度方向拉伸,但是可以缩小。
    • 元素被拉伸来填充交叉轴大小。
    • flex-basis 属性为 auto。
    • flex-wrap 属性为 nowrap。

    弄清楚 Flex 元素的默认值有利于我们更好地进行布局排版。

    实战项目拆解

    看了那么多的 Flex 布局知识点,总感觉干巴巴的,是时候来看看别人在项目中是怎么用的了。

    -w1290-w1290

    上面是我在 CodePen 找到的一个案例,这样的一个布局就是用 Flex 布局来实现的。通过简单的分析,其实我们可以拆解出其 Flex 布局方法,大致如下图所示。

    -w1297-w1297

    首先整体分为两大部分,即导航栏和内容区域,这部分的主轴纵向排列的(flex-direction: column),如上图红框部分。随后在内容区域,又将其分成了左边的导航栏和右边的内容区域,此时这块内容是横向排列的(flex-direction: row),如下上图蓝框部分。

    剩下的内容布局也大致类似,其实就是无限套娃下去。由于偏于原因,这里就不继续深入拆解了,大致的布局思路已经说得很清楚了。

    有了 Flex 布局之后,貌似布局也变得非常简单了。但纸上得来终觉浅,还是得自己实际动手练练才知道容易不容易,不然就变成纸上谈兵了!

    总结

    看到这里,关于 Flex 布局的核心点就介绍得差不多了。掌握好这几个核心的知识点,开始去实践练习基本上没有什么太大的问题了。剩下的一些比较小众的属性,等用到的时候再去查查看就足够了。

    接下来更多的时间,就是找多几个实战案例实践,唯有实践才能巩固所学知识点。后面有机会,我将分享我在 Flex 布局方面的项目实践。

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论