CSS 中的 Flexbox 布局

2025-01-07 pv

我认为,CSS 中最重要的部分,就是布局(Layout)。

布局搭建出整个网页的框架。

一幢摩天大楼,首先关注的,不是玻璃漂不漂亮,而是地基是否足够扎实。

好的框架,应该足够简单,灵活,适应性好。

简单是对开发者而言,心智负担小,开发成本不高,容易维护。

灵活,则要求有弹性(Flexibility)。因为现在终端设备多样,屏幕尺寸差异大,好的布局应该支持响应式设计(Responsive Design),对用户体验更加友好。

这篇文章,不会事无巨细地描述具体 Flexbox 布局怎么使用,而是更多探讨,产生的背景,基本的使用,以及常用场景。

01. 背景

前端开发三剑客中,HTML 提供内容,CSS 负责样式,JavaScript 控制行为。

CSS 对 HTML 内容的渲染,默认按照流(Flow)的方式(可以利用 CSS 中的 position 属性调整)。

就像是排积木,先出现的元素优先占领位置。

元素的大小,通过 盒模型(Box Model)🔗 盒模型(Box Model)制。

流式渲染,叠加盒模型,就构成了 CSS 中最常见,也是最基础的布局手段。

必须承认,这种方式,适应性很强,而且操作精确。平级元素之间的关系(margin),嵌套元素之间的关系(padding),以及元素本身(content & border)的呈现效果,都可以在 CSS 中用对应属性操纵。

缺点是,很复杂,而且比较死板。

上述提到的四个属性,每个又都对应上下左右四个方向。何况,HTML 中元素众多,要控制的属性数量更是倍数上升。

复杂的事物,往往容易出错,同时不易维护。

又由于属性值都是写死(Fixed)的,针对桌面端和移动端应用,需要分别实现,灵活性不足。

02. Flexbox

Flexbox 在一定程度上解决了这个问题。

望文生义,Flexbox 的特点是弹性

比方说,如果我想让一行里的几个元素,均匀分布,类似:

用 Flex 的写法,只需要一行:

display: flex;
justify-content: space-around;

增加新的子元素,不需要任何改动。

同样的效果,如果用盒模型实现,就复杂很多:计算总长度、计算元素数量、计算边距等。

目前 CSS 中有两种弹性布局的方法:Flexbox 和 Grid。

区别在于,Flexbox 通常用于一维布局,Grid 则用于二维布局。更直白的理解,一个是单行,另一个是多行。

在 Flexbox 中,有两个轴:主轴(Main axis)和交叉轴(Cross axis)。

其中,主轴是 Flexbox 中子项目的排列方向(可通过 flex-direction 设置),交叉轴则是垂直于主轴。

Flexbox 中同样存在父子嵌套,用到的 Flexbox 属性也不同。

对于父元素,常见的属性有:

  • display: flex;:启动 flex 布局。

  • flex-direction:定义主轴方向。

    • 常用值:row(默认值,水平布局)、column(垂直布局)。
  • justify-content:沿主轴对齐方式(项目水平分布)。

    • 常用值:flex-startflex-endcenterspace-betweenspace-aroundspace-evenly
  • align-items:沿交叉轴对齐方式(项目垂直对齐)。

    • 常用值:stretchflex-startflex-endcenter
  • flex-wrap:定义是否换行。

    • 常用值:nowrap(默认值),wrapwrap-reverse
  • gap:设置项目之间的间距。

对于子元素,常见的属性有:

  • flex(缩写属性):控制项目的可伸缩性。包括 flex-growflex-shrinkflex-basis

    • 示例:flex: 1;flex: 2 1 0;
  • align-self:覆盖单个项目的对齐方式。

  • order:改变项目的视觉顺序。

怎么使用这里不展开。

有兴趣,可以玩一玩这个小游戏,Flexbox Froggy🔗。很有趣,可以交互式体验 Flexbox 的灵活。

03. 应用场景

这里简单罗列几种常见布局,看看用 Flexbox 实现会有多简洁。

  1. 水平居中

    display: flex;
    justify-content: center;
    align-items: center;

  2. 垂直方向列表

    display: flex;
    flex-direction: column;
    gap: 10px;

  3. 网格布局的替代

    display: flex;
    justify-content: space-between;
    align-items: flex-start;

  4. 卡片式布局

    display: flex;
    flex-wrap: wrap;
    gap: 15px;

04. 总结

如果盒模型是过程式(Imperative),那么 Flexbox 就是声明式(Declarative)。

从抽象程度上讲,后者是比前者高。

显然, 对于开发者,声明式的方式更符合直觉,也更易用。你只需要表明清楚意图,实现上的细节被完全屏蔽。

就像写 SQL,查询的方式如何优化,数据怎么存储,一概不需要操心,背后自有机器任劳任怨地工作。

这就是抽象带来的好处:关注目标,不拘泥于细节。

古语云,将军赶路,不追小兔。

(完)

参考

  1. Block and inline layout in normal flow - CSS: Cascading Style Sheets | MDN🔗
  2. Flexbox Froggy🔗
  3. Flex 布局教程:语法篇 - 阮一峰的网络日志🔗
在 GitHub 上编辑本页面

最后更新于: 2025-01-08T03:24:44+08:00