CSS Flexbox:弹性布局入门 · 第 1 / 5 节

第 1 课:让盒子排成一行的那行声明

本课目标:

  • 说出 display: flex 对容器及其子元素做了什么。
  • 辨认哪些元素会变成 flex item(哪些不会)。
  • 预测 flex item 默认沿主轴排成一行。

先修条件:你会写一个带 class 的 <div> 并设置一个 CSS 属性 | 下一篇 02 >>

没有 Flexbox 时,盒子只会竖着堆。为什么?

往页面上放三个 <div>,它们会竖直堆叠,每个独占一行。这是正常的块级布局,而多年以来,把它们并排放的办法只有浮动和 inline-block 这类到处漏间距 bug 的手段。如果 Flexbox 在你眼里是一堆“粘贴上去再祈祷”的属性,通常是因为没人给你讲它做的第一件事,也就是其他所有属性都依赖的那件事。这一课只讲这第一件事:一条声明,把竖着的堆变成横着的一行。掌握这一点,课程剩下的部分不过是“哪个方向、哪条轴”。

讲解

起步的全部诀窍在这里。你选定容器(包住那些盒子的元素),在它身上设置一个属性:display: flex。该容器的直接子元素随即成为 flex item1。这就是整个开关。

你这么做的那一刻,子元素不再堆叠,而是从左到右排成一行。它们现在沿着容器的主轴排列,主轴默认是水平方向1。你完全没有碰子元素,你改的是父元素,而父元素现在把它的子元素按一条 flex 行摆放。

有一个细节常常绊倒人:只有直接子元素会变成 flex item。如果 flex 容器里放着一张卡片,而卡片内部又有一个标题和一个段落,那么卡片是 flex item,但标题和段落不是。它们属于卡片,比这个容器能安排的层级深了一层2

下面的编辑器是真的。三个盒子正在堆叠。给 .row 加上那条把它变成 flex 容器的声明。

当状态点变成完成时,盒子就在主轴上了。注意你只给 .row 加了 display: flex,没有设宽度、没有浮动、没有对盒子本身做任何事。这就是整门课建立在其上的转变:你通过配置父元素来安排子元素。

完整示例(跟着做)

假设你有一个页头,里面是 logo 和导航,它们正在堆叠:

一步一步说清为什么这样有效。.bar 是容器,所以 display: flex 设在它身上。它的直接子元素是 .logo.links,正好是两个 flex item。设了 display: flex 之后,这两个 item 沿主轴排列,主轴默认水平,所以 logo 和导航在同一行上,logo 在左。你没有给任何子元素设置尺寸,是 flex 行把它们摆好的。

你来试试(填空示例)

你有一个工具栏,三个按钮应该排成一行,但它们正在堆叠。补上缺的那一行:

答案:缺的那一行是 display: flex;。三个 <button> 元素是 .toolbar 的直接子元素,所以它们变成 flex item,沿主轴排成一行。按钮本身什么都不用改。

小结 + 下节课预告

容器上的 display: flex 把它的直接子元素变成 flex item,并沿主轴摆放,主轴默认水平。你通过配置父元素来安排子元素,而 flex 只往下作用一层。下一课我们给两条轴命名,因为一旦有了两个方向,每条轴各有一个对齐属性,justify-contentalign-items 也就终于讲得通了。

Footnotes

  1. MDN: Basic concepts of flexbox — https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Flexible_box_layout/Basic_concepts 2

  2. CSS-Tricks: A Complete Guide to Flexbox — https://css-tricks.com/snippets/css/a-guide-to-flexbox/

练习

01

在你自己的编辑器里新建一个空白 .html 文件,写一个 <div class="row">,里面放三个子 <div>。用浏览器打开,确认三个 div 在堆叠。然后给 .row 加上 display: flex 并刷新。

第 1 级(热身)
完成标准 · 本地勾选
02

在你的 flex 行里嵌一张卡片:给其中一个子 div 加上自己的 <h3> 和 <p>。刷新并观察。<h3> 和 <p> 是被这条 flex 行安排的吗?

第 2 级(进阶)
完成标准 · 本地勾选