CSS Flexbox 弹性布局

Flexbox 是目前最常用的布局工具。它专门解决"一行/一列里如何对齐和分配空间"的问题——以前要靠 float、margin 套娃才能实现的效果,现在三行 CSS 搞定。掌握 Flex,日常 80% 的布局问题就解决了。

1. 什么是 Flex?

Flexbox(Flexible Box)是 CSS3 引入的一维布局模型。所谓"一维"——它一次处理一个方向(一行或一列)的布局。给父元素加 display: flex,它就变成了"弹性容器",它的直接子元素自动变成"弹性项目",沿主轴排列。

/* 给父元素加 display: flex,它的直接子元素就变成了弹性项目 */
.toolbar {
  display: flex;
  justify-content: space-between;  /* 主轴:两端对齐 */
  align-items: center;             /* 交叉轴:垂直居中 */
  gap: 12px;                       /* 子项之间的间距 */
}

/* 子元素会自动横向排列(默认 row 方向) */
/* <div class="toolbar">
     <div class="logo">Logo</div>
     <div class="menu">菜单</div>
     <div class="user">用户</div>
   </div> */

核心概念只有两个轴:

记住这句口诀:justify-content 管主轴,align-items 管交叉轴。换成 row/column 后,两轴对调,但属性不变。

2. justify-content(主轴对齐)

这是 Flex 最常用的属性——决定项目在主轴方向上怎么排。

.container {
  display: flex;
  flex-direction: row;          /* 默认:主轴横向 */

  /* justify-content 控制主轴方向对齐 */

  justify-content: flex-start;    /* 默认:靠左 */
  justify-content: flex-end;      /* 靠右 */
  justify-content: center;        /* 居中 */
  justify-content: space-between; /* 两端对齐,中间均分 */
  justify-content: space-around;  /* 每项左右各占一半空隙 */
  justify-content: space-evenly;  /* 所有空隙完全均分 */
}

最常用的三个:center(居中)、space-between(两端贴边,中间均分,导航栏标配)、space-evenly(所有空隙完全均分,更均衡)。

3. align-items(交叉轴对齐)

控制项目在交叉轴方向上怎么排。最常用的场景是垂直居中

.container {
  display: flex;
  flex-direction: row;

  /* align-items 控制交叉轴(垂直方向)对齐 */

  align-items: stretch;       /* 默认:拉伸填满 */
  align-items: flex-start;    /* 顶部对齐 */
  align-items: flex-end;      /* 底部对齐 */
  align-items: center;        /* 垂直居中 */
  align-items: baseline;      /* 文字基线对齐 */
}

/* 单独给某个子项设交叉轴对齐 */
.special {
  align-self: flex-end;       /* 只有它靠底 */
}

重点:align-items: center 让子元素在垂直方向居中——这以前要靠 line-heightposition 套娃才能实现,现在一行搞定。align-self 可以单独覆盖某个子项的对齐方式。

4. flex 属性(项目如何分配空间)

flex 是写在子元素上的属性,决定它如何分享剩余空间。这是 Flex 强大的核心。

.container {
  display: flex;
}

/* flex 是 flex-grow flex-shrink flex-basis 的简写 */
.item-a { flex: 1; }    /* 占 1 份,平分剩余空间 */
.item-b { flex: 2; }    /* 占 2 份,是 a 的两倍宽 */
.item-c { flex: 0 0 200px; }  /* 不放大不缩小,固定 200px */

/* 详解:
   flex-grow:   放大比例(剩余空间怎么分)
   flex-shrink: 缩小比例(空间不够时谁让步)
   flex-basis:  初始尺寸(优先于 width)
*/

简写 flex: 1 是最常用的,等价于 1 1 0%——可放大、可缩小、初始尺寸 0(完全靠 grow 分配)。背下来即可。

5. flex-direction 与换行

主轴方向可以切换——横向变纵向,导航栏变垂直菜单。

.container {
  /* 主轴方向 */

  flex-direction: row;              /* 默认:横向,从左到右 */
  flex-direction: row-reverse;      /* 横向,从右到左 */
  flex-direction: column;           /* 纵向,从上到下 */
  flex-direction: column-reverse;   /* 纵向,从下到上 */

  /* 是否换行 */

  flex-wrap: nowrap;    /* 默认:不换行,挤一起 */
  flex-wrap: wrap;      /* 放不下就换行 */

  /* 简写 */
  flex-flow: row wrap;
}

flex-direction: column 非常有用:做卡片(图片在上、标题在中、按钮在下)、垂直菜单都靠它。注意切到 column 后,主轴变成纵向,justify-content 控制的就是垂直方向了。

flex-wrap: wrap 让项目放不下时自动换行——做标签云、卡片墙时必备。默认 nowrap 会让项目硬挤一行,导致内容被压缩。

6. 经典用法 1:完美居中

Flex 出现前,"未知尺寸元素垂直居中"是 CSS 头号难题。现在三行解决:

/* Flex 最经典的用法:完美居中 */
/* 水平 + 垂直方向都居中,无论子元素多大 */
.hero {
  display: flex;
  justify-content: center;   /* 水平居中 */
  align-items: center;       /* 垂直居中 */
  min-height: 100vh;         /* 高度撑满视口 */
}

.hero .content {
  /* 子元素自动居中,不用算 margin/padding */
  text-align: center;
}

这是现代居中的标准写法,完全替代了以前的 position + transformline-heighttable-cell 等各种 hack。背下来。

7. 经典用法 2:三段式导航栏

logo 在左、菜单在中、用户在右——这是页面顶部的标配布局。flex: 1 让中间菜单占满剩余空间。

/* 经典导航栏:logo 在左,菜单在中,用户在右 */
.navbar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 24px;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0,0,0,.05);
}

.navbar .logo { flex: 0 0 auto; }    /* 不放大 */
.navbar .menu {
  flex: 1;                            /* 占满中间 */
  display: flex;
  gap: 20px;
  justify-content: center;
}
.navbar .user { flex: 0 0 auto; }     /* 不放大 */

8. gap 间距

以前给 flex 项目设间距,要靠 margin 一堆计算,还得处理首尾多余 margin。现在用 gap 一行搞定——只在项目之间生效,首尾没有多余。

<style>
.row {
  display: flex;
  gap: 12px;     /* 子项之间都是 12px,首尾无多余 */
}
</style>

gap 在 Flex、Grid、多列布局里都能用,是现代 CSS 的标配。浏览器支持已经很好,放心用。

9. Flex 实战经验

小结

Flexbox 是现代 CSS 布局的基石。核心就两组属性:justify-content 管主轴、align-items 管交叉轴;子元素用 flex 分配空间;用 gap 设间距;完美居中三行搞定。下一篇讲 Grid 网格布局——Flex 的好搭档,专门处理二维整页布局。

← 上一篇 CSS 颜色与背景

下一篇 CSS Grid 网格布局

✈️💬