Flexbox弹性布局基础:主轴与交叉轴

Flexbox,说白了就是CSS里最实用的布局方案之一。我刚开始做跨平台适配时,还在用float和inline-block硬撑,直到遇到Flexbox——嗯,真香。

今天咱们把Flexbox的核心概念拆开揉碎了讲。你只要掌握这几个点:主轴与交叉轴、flex-direction、justify-content、align-items、flex-wrap。搞定它们,90%的布局场景你都能轻松应对。

主轴与交叉轴:布局的坐标系

Flexbox布局里有两个轴:主轴和交叉轴。你可以把它们想象成一个十字坐标系。

主轴是Flex容器里项目排列的方向。交叉轴则垂直于主轴。

举个例子:如果主轴是水平方向(从左到右),那交叉轴就是垂直方向(从上到下)。反过来,主轴是垂直方向,交叉轴就是水平方向。

我个人习惯把主轴理解为「主要排列方向」,交叉轴就是「次要排列方向」。这样记不容易乱。

核心要点:主轴方向由flex-direction决定,交叉轴永远垂直于主轴。

flex-direction:控制主轴方向

flex-direction有四个值:

值 主轴方向 实际效果
row 水平,从左到右 默认值,项目水平排列
row-reverse 水平,从右到左 项目水平反向排列
column 垂直,从上到下 项目垂直排列
column-reverse 垂直,从下到上 项目垂直反向排列

我在项目中遇到过一个问题:用row-reverse时,视觉顺序变了,但DOM顺序没变。这对屏幕阅读器有影响,做无障碍适配时要小心。

.container {
  display: flex;
  flex-direction: row; /* 默认值,可以省略 */
}

.container-vertical {
  display: flex;
  flex-direction: column; /* 垂直排列 */
}

justify-content:主轴上的对齐

justify-content控制项目在主轴上的分布方式。说白了就是「怎么排成一排」。

常用的值:

  • flex-start:从主轴起点开始排列(默认)
  • flex-end:从主轴终点开始排列
  • center:居中排列
  • space-between:两端对齐,项目之间间距相等
  • space-around:每个项目两侧间距相等
  • space-evenly:所有间距完全相等

小技巧:space-between和space-around的区别,我刚开始也搞混。记住:between是「贴边」,around是「留边」。space-evenly是CSS后来加的,兼容性稍差,但效果最均匀。

.container {
  display: flex;
  justify-content: center; /* 主轴居中 */
}

.container-between {
  display: flex;
  justify-content: space-between; /* 两端对齐 */
}

align-items:交叉轴上的对齐

align-items控制项目在交叉轴上的对齐方式。它和justify-content是「一对兄弟」——一个管主轴,一个管交叉轴。

常用值:

  • stretch:拉伸填满容器高度(默认)
  • flex-start:交叉轴起点对齐
  • flex-end:交叉轴终点对齐
  • center:交叉轴居中
  • baseline:按文字基线对齐

为什么stretch是默认值?因为Flexbox设计时考虑到「容器高度自适应」的场景。你想想看,如果每个项目高度不同,stretch能让它们统一高度,视觉上更整齐。

注意:align-items的stretch只在项目没有设置固定高度(或宽度,取决于交叉轴方向)时才生效。我曾经踩过这个坑——给项目设了height: 100px,结果stretch不工作了,排查了半天才发现。

.container {
  display: flex;
  align-items: center; /* 交叉轴居中 */
  height: 200px;
}

.container-top {
  display: flex;
  align-items: flex-start; /* 顶部对齐 */
}

flex-wrap:换行控制

默认情况下,Flexbox里的项目不会换行,它们会挤在一行里。flex-wrap就是用来控制这个行为的。

三个值:

  • nowrap:不换行(默认),项目会压缩或溢出
  • wrap:换行,从上到下排列
  • wrap-reverse:换行,从下到上排列

我记得做移动端适配时,经常用flex-wrap: wrap来处理卡片列表。屏幕宽了就多排几列,窄了就自动换行,省心得很。

.card-list {
  display: flex;
  flex-wrap: wrap; /* 允许换行 */
  gap: 16px; /* 项目间距,CSS新特性 */
}

.card {
  width: 200px;
  height: 150px;
}

知识体系总览

下面这张图帮你理清Flexbox的核心逻辑:

Flexbox弹性布局核心结构 Flex容器 主轴 (flex-direction: row) 交叉轴 项目1 项目2 项目3 项目4 justify-content控制主轴对齐 | align-items控制交叉轴对齐 | flex-wrap控制换行

实战组合:一个完整的例子

把上面这些属性组合起来,就能做出各种布局。来看一个导航栏的例子:

.navbar {
  display: flex;
  justify-content: space-between;  /* 左右两端对齐 */
  align-items: center;             /* 垂直居中 */
  padding: 0 20px;
  height: 60px;
  background: #333;
  color: #fff;
}

.nav-links {
  display: flex;
  gap: 24px;  /* 链接之间的间距 */
  list-style: none;
}

/* 移动端适配:导航链接换行 */
@media (max-width: 600px) {
  .navbar {
    flex-wrap: wrap;
    height: auto;
    padding: 10px;
  }
  
  .nav-links {
    flex-wrap: wrap;
    justify-content: center;
  }
}

避坑指南:我曾经在项目里同时用了justify-content: center和flex-wrap: wrap,结果换行后项目没有居中,而是左对齐了。后来才发现——flex-wrap换行后,每一行都变成了独立的「flex行」,justify-content只对当前行生效。解决办法是给容器加个宽度限制,或者用gap配合margin来微调。

总结一下

Flexbox的核心就这五点:

  1. 主轴与交叉轴——理解这两个轴,就理解了Flexbox的坐标系
  2. flex-direction——决定主轴方向,row还是column
  3. justify-content——主轴上的排列方式
  4. align-items——交叉轴上的对齐方式
  5. flex-wrap——要不要换行

记住一个口诀:「主轴方向direction定,主轴对齐justify,交叉对齐align,换行靠wrap。」

嗯,这些基础打牢了,后面讲flex-grow、flex-shrink、flex-basis这些进阶属性时,你就能轻松上手了。

可可精品资料库