Flexbox 完全指南:从此告别浮动,拥抱一维战神

0 阅读7分钟

还在用float做导航?还在为垂直居中写positiontransform?今天我们来认识一位布局界的“一维战神”——Flexbox。它专治各种居中、等分、排列难题,让你写布局像搭积木一样简单。

前言

回想那些年被float支配的日子:清浮动要写clearfix,垂直居中要算半天,几个元素等宽还得用百分比小心翼翼……直到Flexbox的出现,前端布局才真正迎来了春天。

Flexbox的全称是Flexible Box Layout Module,翻译过来就是“弹性盒子”。它的核心思想是:让容器有能力改变子项的宽度、高度、顺序,以最好地填充可用空间。尤其擅长处理一维布局(也就是一行或一列)。今天我们就来彻底掌握这个“一维战神”。

一、Flexbox的两大核心:容器与项目

要使用Flexbox,你只需要在父元素上设置display: flexdisplay: inline-flex。这时,父元素成为flex容器,它的直接子元素自动成为flex项目

.container {
  display: flex;  /* 容器开启flex模式 */
}

就像一支军队有了指挥官,所有士兵(项目)都听从容器(指挥官)的调遣。

二、轴:Flexbox的方向感

Flexbox里有两条轴:主轴交叉轴,所有排列都围绕这两条轴进行。

  • 主轴:默认水平方向,从左到右。你可以通过flex-direction改变它的方向。
  • 交叉轴:始终垂直于主轴。

想象你手里拿着一排士兵,你可以命令他们横着站(主轴水平),也可以竖着站(主轴垂直),甚至可以倒着站。这就是flex-direction的作用。

.container {
  flex-direction: row;            /* 默认值,主轴水平,从左到右 */
  flex-direction: row-reverse;    /* 主轴水平,从右到左 */
  flex-direction: column;         /* 主轴垂直,从上到下 */
  flex-direction: column-reverse; /* 主轴垂直,从下到上 */
}

三、主轴上的排列:justify-content

justify-content控制项目在主轴上的对齐方式。这是最常用的属性之一。

.container {
  justify-content: flex-start;    /* 默认,左对齐/上对齐 */
  justify-content: flex-end;      /* 右对齐/下对齐 */
  justify-content: center;        /* 居中 */
  justify-content: space-between; /* 两端对齐,项目之间间距相等 */
  justify-content: space-around;  /* 每个项目两侧间距相等 */
  justify-content: space-evenly;  /* 项目之间间距相等,边缘间距也是项目间距的一半?不,是均匀分布,包括两端 */
}

其中space-betweenspace-evenly尤其好用:一个让首尾贴边,中间均分;一个让所有间隙相等,包括两端。

四、交叉轴上的对齐:align-items 与 align-content

1. align-items:单行项目的交叉轴对齐

当所有项目在一行(或一列)时,用align-items控制它们在交叉轴上的对齐方式。

.container {
  align-items: stretch;   /* 默认,如果项目未设置高度,则拉伸填满容器 */
  align-items: flex-start; /* 交叉轴起点对齐 */
  align-items: flex-end;   /* 交叉轴终点对齐 */
  align-items: center;     /* 交叉轴居中 */
  align-items: baseline;   /* 按第一行文字基线对齐 */
}

这个属性就是垂直居中的神器:只要容器有高度,设置align-items: center,项目就能垂直居中(当然主轴方向得是row)。

2. align-content:多行项目的整体对齐

当容器在交叉轴方向有多余空间,且项目有多行时,用align-content控制多行整体的对齐方式。它和justify-content类似,只不过作用于交叉轴。

.container {
  flex-wrap: wrap;        /* 先允许换行 */
  align-content: stretch;   /* 默认,拉伸占满 */
  align-content: flex-start;
  align-content: flex-end;
  align-content: center;
  align-content: space-between;
  align-content: space-around;
  align-content: space-evenly;
}

注意:如果项目只有一行,align-content不起作用。

五、项目的灵活性:flex 相关属性

项目自己也可以设置属性,控制自己的尺寸、排列顺序等。

1. flex-grow:如何分剩余空间

当容器还有剩余空间时,flex-grow决定项目是否放大、放大多少。默认值为0,即不放大。如果所有项目都设为1,则它们等分剩余空间;如果一个为2,其他为1,则2的那个多占一倍。

.item {
  flex-grow: 1;   /* 所有项目等分剩余空间 */
}

2. flex-shrink:空间不够时如何缩小

当容器空间不足时,flex-shrink决定项目是否缩小、缩小多少。默认值为1,即所有项目等比例缩小。设为0的项目不会缩小。

.item {
  flex-shrink: 0;   /* 打死我也不缩小 */
}

3. flex-basis:项目的基础尺寸

flex-basis定义项目在分配空间前的默认尺寸,可以理解为在主轴上的“初始宽度”(主轴水平时)。优先级高于width(如果同时设置)。默认值为auto,即参考项目本身的尺寸。

.item {
  flex-basis: 200px;   /* 我希望基础宽度是200px */
}

4. flex 简写

通常我们会用flex属性将上面三个合起来写:flex: grow shrink basis。常见值:

  • flex: 1 = flex: 1 1 0%(等分剩余空间)
  • flex: auto = flex: 1 1 auto(根据内容分配空间)
  • flex: none = flex: 0 0 auto(固定尺寸,不弹性)

六、项目的排序与对齐覆盖

1. order:改变项目顺序

默认所有项目的order为0,按源码顺序排列。你可以给某个项目设置更大的order让它往后排,或更小的order让它往前排。支持负数。

.item:last-child {
  order: -1;   /* 最后一个变成第一个 */
}

2. align-self:覆盖容器的 align-items

如果你想单独改变某个项目在交叉轴上的对齐方式,可以用align-self,它的取值和align-items一样。

.item.special {
  align-self: flex-end;   /* 单独沉底 */
}

七、实战:常见的Flexbox布局套路

1. 水平垂直居中

最简单的居中方案:

.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}

无论子元素是一个还是多个,都能完美居中。

2. 导航栏:Logo左,菜单中,登录右

<nav class="nav">
  <div class="logo">Logo</div>
  <ul class="menu">
    <li>首页</li>
    <li>产品</li>
    <li>关于</li>
  </ul>
  <div class="login">登录</div>
</nav>
.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.menu {
  display: flex;
  gap: 20px;
  list-style: none;
}

如果想菜单绝对居中(不受左右宽度影响),可以给.menumargin: 0 auto

3. 等分布局

比如三个卡片等宽,间距固定:

.container {
  display: flex;
  gap: 20px;
}
.item {
  flex: 1;   /* 三个项目等分剩余空间,宽度相等 */
}

4. 圣杯布局(经典三栏)

左右固定宽度,中间自适应:

.container {
  display: flex;
}
.left {
  width: 200px;
}
.right {
  width: 200px;
}
.main {
  flex: 1;   /* 中间占满剩余空间 */
}

5. 底栏自动贴底

页面内容不足时,footer贴在底部;内容多时,footer被推下:

<body style="display: flex; flex-direction: column; min-height: 100vh;">
  <header>...</header>
  <main style="flex: 1;">...</main>
  <footer>...</footer>
</body>

八、常见坑点与避坑指南

1. 浮动失效

一旦元素成为flex项目,它的floatclearvertical-align都会失效。所以放心用flex,不用再担心浮动了。

2. margin: auto 的妙用

在flex容器中,设置某个项目的margin: auto,它会自动吸收剩余空间,实现“推挤”效果。例如让一个项目单独靠右:

.container {
  display: flex;
}
.item.move-right {
  margin-left: auto;   /* 把自己挤到右边 */
}

3. 文本溢出省略号

在flex项目中设置文本省略号时,可能需要给项目设置min-width: 0overflow: hidden,因为flex项目默认不会缩小到内容最小宽度以下。

.item {
  min-width: 0;        /* 允许项目缩小到比内容宽度小 */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

4. gap 属性

gap是较新的属性,可以方便地设置项目之间的间距,不用再为margin头疼。支持row-gapcolumn-gap,也可简写gap: 10px 20px

.container {
  display: flex;
  gap: 20px;   /* 项目之间左右、上下间距都是20px(如果换行) */
}

九、总结

Flexbox是现代布局的基石,掌握它,你就能轻松应对绝大多数一维布局场景。再回顾一下核心:

  • 容器设置display: flex,开启弹性世界。
  • flex-direction定主轴,用justify-content定主轴排列,用align-items定单行交叉轴对齐。
  • 项目用flex控制弹性,用order改变顺序,用align-self独立对齐。
  • 记住几个常用套路:居中、等分、导航、贴底。
  • 避坑:浮动失效、margin auto推挤、最小宽度限制。

Flexbox并不难,关键是理解“主轴”和“剩余空间分配”这两个概念。多动手写几个例子,你就能成为布局大师。

如果你喜欢这篇文章,欢迎点赞、收藏、分享。明天我们接着讲Grid布局——二维世界的终极武器,敬请期待!


明日预告:Grid网格布局从入门到精通——用网格思想重构网页,让二维布局不再头疼。