CSS 布局与样式约 8 分钟

Flex 布局的三个属性,先把主轴想清楚

刚学 Flex 时最容易把 justify-content 和 align-items 记混。这篇笔记从主轴出发,把方向、对齐与伸缩三件事拆开,再说明什么时候应该换成 Grid。

浏览器中展示 Flexbox 主轴与交叉轴对齐关系的示意图
本文目录

Flex 布局看起来属性很多,真正决定结果的只有三件事:方向决定谁是主轴,对齐属性只作用在各自的轴上,伸缩比例决定剩余空间怎么分。把这三件事分开记,比背属性表有用得多。

先分清主轴和交叉轴

给一个容器加上 display: flex 之后,它会多出两条轴:主轴由 flex-direction 决定,另一条就是交叉轴。justify-content 永远作用于主轴,align-items 永远作用于交叉轴。所以只要改变 flex-direction,这两个属性的效果会整体旋转九十度。

CSS
.row {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
}

.column {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: center;
}

同样的两个属性值,在 .row 里是左右分布、上下居中,在 .column 里变成上下分布、左右居中。判断对齐是否正确,先看主轴方向,比反复改属性快。

justify-content 和 align-items 不是一组

很多人把它们当成一对开关,其实一个是「怎么分配整行的空间」,一个是「行内的元素在交叉轴上怎么摆」。当容器有多行时,还需要 align-content,它处理的是多行之间的间距,而不是单行里的元素。

一个快速判断方法

  • 想调整元素之间的距离或靠边:用 justify-content
  • 想让元素在另一条轴上居中或拉伸:用 align-items
  • 容器换行后多行之间距离不对:用 align-content
  • 单个元素想单独偏移:用 align-self

flex 简写里的三个值

flex: 1 是最常见的写法,它等价于 flex-grow: 1、flex-shrink: 1、flex-basis: 0%。注意 basis 是 0% 而不是 auto,这让元素在分配剩余空间前先被压成内容以外的零宽基准,所以多个 flex: 1 的子项会平分宽度,哪怕内容长短差很多。

CSS
.equal {
  flex: 1 1 0%;
}

.keeps-content-width {
  flex: 0 1 auto;
}

.never-shrink {
  flex: 0 0 auto;
}
如果布局结果和预期差很多,先检查 flex-basis,而不是先怀疑浏览器。

什么时候不该用 Flex

Flex 的强项是一维排列:一行按钮、一条工具栏、一个居中的卡片。遇到需要同时对齐行和列的情况,比如图片墙、卡片网格、带固定侧栏的页面骨架,Grid 的属性表达更直接。判断标准很简单:如果你需要写多层嵌套的 Flex 才能对齐两端,就该换 Grid 了。

  • 一维排列、元素数量不固定:Flex
  • 二维对齐、行列都要控制:Grid
  • 元素之间间距规则且需要换行:Grid 的 gap 更省心
  • 需要按比例分配剩余宽度:两者都能做,Flex 更贴近语义

下一篇笔记会用 Grid 重写同样的卡片布局,对比两种写法的属性数量,就能看出选择布局模型其实是在选择更短的表达。

相关阅读