zzxworld

学习 CSS Flex 弹性盒子布局

我从学习 Web 编程到工作至今,大致经历了两个 CSS 布局时期。第一个时期是 Table 嵌套布局,第二个时期是 CSS 浮动定位布局。后来因为工作重心转移到了后端开发的原因,我的 CSS 布局概念基本停滞在浮动定位布局时期。即便 CSS3 已经盛行了这么多年,我对它提供的新布局属性还不是很熟悉。为补齐这方面的短板,我准备从 Flex 开始学习新的布局方式。

Flex 布局方式更正式的名称是 Flexible Box,中文名称:弹性盒。它在控制元素的布局方向上比较简单,只能从单个纬度来控制元素的显示。也就是说使用 Flex 布局,只能把元素以「行」方式,或是以「列」方式来操控。所以 Flex 也被称之为「一维」布局方式。

使用 Flex 布局

通过 CSS 的 display 属性可以指定标签以 Flex 方式显示:

display: flex;

来准备一段简单的代码,这是 HTML 部分的:

<div class="box">
    <div class="one">zzxworld</div>
    <div class="two">这是<br/>一个 Flexbox 布局演示</div>
    <div class="three">其他演示内容</div>
</div>

这是 CSS 部分的:

.one {
    background: orange;
}

.two {
    background: gold;
}

.three {
    background: yellow;
}

.box {
    background: silver;
}

在没有使用 Flex 弹性布局时,它的显示是这样的:

Screenshot no flexbox

如果给 .box 的 div 标签用上 Flex 显示属性:

.box {
    background: black;
    display: flex;
}

它里面的三个 div 会显示成一行:

Screenshot flex

Flexbox 还有另外一个 display 属性值 inline-flex。使用它会以行内元素的方式显示 Flex 容器元素。比如上面的例子,用上 inline-flex 后会这样来显示:

Screenshot inline flex

没有了灰色背景,因为 .box 以行内元素的方式来显示了。

控制可用空间

在上面的例子中可以看到,当把 .box 设置为弹性盒容器后,它里面包含的 div 元素默认都会以自己内容长度来显示。因为内容总长度小于弹性盒的宽度,这让 .box 弹性盒子的灰色背景都露了出来。假设现在想要通过 Flex 来创建三栏布局,我更希望看到的结果是弹性盒内部的标签能够自动撑满整个空间,这通过 flex 属性可以实现。

.two 添加一行 CSS 代码:

.two {
    background: gold;
    flex: auto;
}

这表示让中间的 div 标签使用弹性盒子的空白空间。来看看效果:

Screenshot flex 1

通过 flex 属性还可以实现「栅栏」式布局功能,比如把整个弹性盒的宽度分成 4 等份,三个 div 标签两边各占一份,中间的占两份:

.one {
    background: orange;
    flex: 1 1 auto;
}

.two {
    background: gold;
    flex: 2 1 auto;
}

.three {
    background: yellow;
    flex: 1 1 auto;
}

上面的定义显示效果如下:

Screenshot flex 2

控制显示方向

在弹性盒标签上使用 flex-direction 属性可以定义盒内元素的排列方向。比如从右到左排列:

.box {
    background: silver;
    display: flex;
    flex-direction: row-reverse;
}

来看看效果:

Screenshot flex reverse list.png

可以发现,第一个 div 和第三个 div 交换了显示位置。

控制对齐

Flex 弹性盒布局有四个控制对齐的 CSS 属性:

  • justify-content:在弹性盒容器上定义,控制元素标签在主轴上的对齐方式。
  • align-items:在弹性盒容器上定义,控制元素在交叉轴上的对齐方式。
  • align-self:在元素标签上定义,控制单个标签在交叉轴上的对齐方式。
  • align-content:在元素标签上定义,当弹性盒容器中存在较多元素,且使用换行方式显示时,用这个属性可以控制标签元素在交叉轴的对齐方式。

上面的 4 个 CSS 属性涉及到两个概念:主轴和交叉轴。主轴是使用 Flex 弹性布局时设置的对齐方向。由于这个对齐方向可以通过上面「控制显示方向」所说的属性来定义,所以可以是从左到右,也可以是从上到下。主轴方向确定后,交叉轴就是跟主轴十字交叉的方向。

把演示的 CSS 代码调整为如下:

html, body, .box {
    margin: 0;
    padding: 0;
    height: 100%;
}

.one {
    background: orange;
}

.two {
    background: gold;
}

.three {
    background: yellow;
}

.box {
    background: silver;
    display: flex;
    align-items: center;
    justify-content: center;
}

上面这段 CSS 代码使用了 align-itemsjustify-content 对齐属性,使用它们让容器盒子中的元素实现水平和垂直居中显示。为了配合垂直居中的效果,给 html, box.box 标签设置了 height: 100% 的属性。

上面这段 CSS 的显示效果如下:

Screenshot align center

总结

Flex 弹性盒布局和我之前擅长表格布局以及定位布局相比,方便和易用了很多。通过这次对 Flex 布局方式的了解,又加深了一些对它能力的了解。本文总结的比较粗浅,仅做介绍和推荐。想要深入学习的话还是建议参考 MDN 的《CSS 弹性盒子布局》教程来学习。后续我会尝试通过实例的方式来深入学习它在实际场景中的用法。