六维教程

CSS Flexbox 初识

为什么需要 Flexbox

在学 Flexbox 之前,我们先回顾一下传统布局的痛点。用浮动做水平排列是最经典的做法,但 float 有个老毛病,父元素会因为子元素全部脱离文档流而塌陷,高度变成 0,还得额外写一个清浮动的技巧,又丑又麻烦。

垂直居中更是老大难。margin: auto 在普通文档流里只对水平方向有效,想让一个盒子在父元素里垂直居中,得用绝对定位加负 margin 之类的黑魔法,宽度还得写死。

还有子元素的尺寸弹性分配。三个按钮想均分一整行宽度,用传统方式需要自己计算百分比,还得处理边框和 padding 造成的误差,内容改了又得重新算。

这些问题的共同根源在于,传统布局没有把”排列方向”和”空间分配”当回事。Flexbox 就是为这两个问题而生的。它是整个系列里最实用的一章,学会它,你写的布局代码能少一半。

一维布局模型

Flexbox 是一维布局模型。一维的意思是,它一次只管一个方向,要么管水平方向,要么管垂直方向,不像 Grid 那样两个方向同时管。记住这一点,后面的内容都好理解。

两个核心概念

使用 Flexbox 只需要两个角色。

  • flex 容器,给父元素加 display: flex 就得到它
  • flex 项目,容器里的直接子元素自动变成它

“直接子元素”这几个字要划重点,嵌套的孙元素不参与外层容器的 Flexbox 布局,它只是在某个 flex 项目内部继续排列而已。

主轴与交叉轴

Flexbox 里有两个轴的概念。

  • 主轴,默认从左到右,是项目排列的方向
  • 交叉轴,默认从上到下,与主轴垂直

“默认”两个字很重要,因为 flex-direction 可以交换这两个轴的方向。所以请记牢,主轴不是”水平轴”的别名,它是”由 flex-direction 决定的方向”。如果 flex-direction 设成 column,主轴就变成从上到下了。

第一个例子

下面是最简单的水平排列示例,每行都解释一下。

<div class="box">
  <div class="item">A</div>
  <div class="item">B</div>
  <div class="item">C</div>
</div>
.box {
  display: flex;          /* 开启 flex,子元素排成一排 */
}

.item {
  padding: 20px;
  margin: 8px;
  background: #eee;       /* 加点背景方便观察 */
}

display: flex 是开关,声明后 .box 成为 flex 容器,三个 .item 自动变成 flex 项目。padding 和 margin 在 flex 布局里照常生效,所以项目之间有 8px 间隔,各自也有内边距。

注意,这三个项目默认贴着容器左侧排,宽度就是内容宽度,不会自动拉伸占满整行。怎么让它们瓜分剩余空间,是下一篇文章的主角。

行内元素也适用

Flexbox 对行内元素同样适用。如果父容器是 span,display: flex 之后,它内部的子元素会自动”块级化”变成 flex 项目,可以设置宽高、margin 这些块级才有的属性。这在做图标加文字的组件时很方便。

span.icon-box {
  display: flex;   /* span 也能成为 flex 容器 */
}

小结

这一篇把地基打好了。记住三件事,flex 容器加 display: flex 开启,直接子元素变成 flex 项目,flex 是一维模型,主轴方向由 flex-direction 决定。下一篇讲容器上的六个属性,CSS 属性关键字里学过的 auto 等关键字,在它们身上会大量出现。

上一篇
CSS 传统布局实战
下一篇
CSS flex布局 基本概念