跳到主要内容

Flexbox 弹性布局实战:主轴交叉轴讲清楚, 居中和自适应一次搞定

用一篇文章把 Flexbox 的主轴交叉轴、flex-direction、justify-content、align-items、wrap 全部讲透, 配上一段真实可粘贴的居中 CSS, 再说清它和 Grid 的分工, 看完就会写。

发布于 作者 李雷
#flexbox #css #前端 #布局 #弹性布局

Flexbox 弹性布局实战:主轴交叉轴讲清楚, 居中和自适应一次搞定

写了几年 CSS, 我发现 Flexbox 真正卡住人的从来不是属性名, 而是"这个值到底沿哪条轴移动"。背不下来不要紧, 想明白主轴和交叉轴这两条线, 八成的对齐问题当场就化开了。这篇就按这个顺序把 Flexbox 讲一遍, 从两条轴, 到居中, 到自适应, 再到它和 Grid 的分工。

先认两条轴:主轴和交叉轴

给容器写上 display: flex, 它内部立刻出现两条看不见的方向线。

  • 主轴 (main axis):由 flex-direction 决定。默认 row, 主轴是水平方向, 子项从左往右排;改成 column, 主轴变成垂直方向, 子项从上往下排。
  • 交叉轴 (cross axis):永远和主轴垂直。row 时它是垂直方向, column 时它是水平方向。

记住这一点, 后面两个最常用的属性就各归其位了:

  • justify-content主轴上的分布。它的六个值, flex-startcenterflex-endspace-betweenspace-aroundspace-evenly, 都是在主轴这条线上把子项往哪挤、留多少缝。
  • align-items交叉轴上的对齐。flex-start 贴一头、center 居中、flex-end 贴另一头、stretch 撑满。

所以"在 row 容器里想做垂直居中却用 justify-content"是头号翻车现场:垂直是交叉轴, 该用 align-items。一旦你脑子里有这两条轴, 这种错就犯不出来了。

justify-content 和 align-items 配合起来

把两个属性放一起, 大部分对齐需求就齐活了。justify-content 决定子项沿主轴怎么散开, align-items 决定它们在交叉轴上贴哪条边。比如一个工具栏想要"主轴两端对齐、交叉轴垂直居中", 就是 justify-content: space-betweenalign-items: center

space-between 是首尾子项贴边、中间均分;space-around 是每个子项左右各留一半的缝;space-evenly 是所有缝都相等。三者差别用嘴说总是绕, 真正看一眼预览就懂了。

一段真正能粘的居中 CSS

经典需求"把一个 div 居中", 在 Flexbox 里就是两行:

.container {
  display: flex;
  justify-content: center; /* 主轴居中:水平 */
  align-items: center;     /* 交叉轴居中:垂直 */
  min-height: 100vh;
}

输入是这四行声明, 输出就是容器里那个子项稳稳停在正中间。这是老写法 position: absolute; transform: translate(-50%, -50%) 的现代替代:没有 magic number, 容器多大都成立, 子项内容变了也不会散。我自己第一次用这两行替掉那串 transform 时, 反应是有点不敢信居然这么短, 后来再没回去过。

想动手实测每个值的差别, 直接打开 Flexbox 可视化 Playground 与 CSS 生成器, 在真实 flex 盒子上调 justify-contentalign-items, 改一下预览立刻重排, 满意了把它生成好的 CSS 复制走就行。

flex-wrap 与自适应

默认 flex-wrap: nowrap, 子项再挤也不换行, 宁可被压窄。改成 wrap, 容器放不下时子项自动落到下一行, 这是做标签云、卡片墙、画廊这类自适应布局的基础。

要注意一个依赖关系:align-content 只在换行后才有意义。它对齐的是多条 flex 行之间的关系, 单行容器只有一行, 没有行可排, 所以 nowrap 时它完全失效。两个对齐属性别搞混:align-items 排的是行子项, align-content 排的是行与行之间的间距。

至于子项自身的弹性, 交给三件套:flex-grow (有剩余空间时按比例分)、flex-shrink (空间不够时按比例收)、flex-basis (分配前的起始尺寸)。三张卡片想不管内容多少都等宽, 给每个子项设 flex: 1, 也就是 flex-grow: 1; flex-shrink: 1; flex-basis: 0%, 它们从 0 起步平分空间, 内容再不一样也撑不开差距。

Flexbox 和 Grid 怎么分工

经常有人问到底该用哪个, 我的判断很简单:一维用 Flex, 二维用 Grid

  • Flexbox 是一维布局, 一次只管一条轴上的排布。导航栏、按钮组、一行卡片、把某个元素推到另一端, 这些"沿一条线排"的场景它最顺手。
  • Grid 是二维布局, 同时管行和列。整页框架、图片矩阵、需要行列精确对齐的表单, 该上 Grid。

两者不是对立的, 实际项目里常常 Grid 搭页面骨架、每个格子内部再用 Flex 对齐内容。想做二维的网格布局, 可以去 CSS Grid 可视化生成器 直接拖出列和行, 跟 Flexbox 的思路对照着看, 一维和二维的边界会清楚很多。

小结

Flexbox 不难, 难的是没先把两条轴立起来就开始背属性。记住主轴归 justify-content、交叉轴归 align-items, 换行靠 flex-wrap, 弹性靠 grow / shrink / basis 三件套, 居中两行声明搞定。一维场景交给它, 二维交给 Grid。剩下的, 边调预览边记最快。


Made by Toolora · Updated 2026-06-13