Flexbox 完全指南:从此告别浮动,拥抱一维战神
还在用
float做导航?还在为垂直居中写position加transform?今天我们来认识一位布局界的“一维战神”——Flexbox。它专治各种居中、等分、排列难题,让你写布局像搭积木一样简单。
前言
回想那些年被float支配的日子:清浮动要写clearfix,垂直居中要算半天,几个元素等宽还得用百分比小心翼翼……直到Flexbox的出现,前端布局才真正迎来了春天。
Flexbox的全称是Flexible Box Layout Module,翻译过来就是“弹性盒子”。它的核心思想是:让容器有能力改变子项的宽度、高度、顺序,以最好地填充可用空间。尤其擅长处理一维布局(也就是一行或一列)。今天我们就来彻底掌握这个“一维战神”。
一、Flexbox的两大核心:容器与项目
要使用Flexbox,你只需要在父元素上设置display: flex或display: 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-between和space-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;
}
如果想菜单绝对居中(不受左右宽度影响),可以给.menu加margin: 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项目,它的float、clear、vertical-align都会失效。所以放心用flex,不用再担心浮动了。
2. margin: auto 的妙用
在flex容器中,设置某个项目的margin: auto,它会自动吸收剩余空间,实现“推挤”效果。例如让一个项目单独靠右:
.container {
display: flex;
}
.item.move-right {
margin-left: auto; /* 把自己挤到右边 */
}
3. 文本溢出省略号
在flex项目中设置文本省略号时,可能需要给项目设置min-width: 0或overflow: hidden,因为flex项目默认不会缩小到内容最小宽度以下。
.item {
min-width: 0; /* 允许项目缩小到比内容宽度小 */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
4. gap 属性
gap是较新的属性,可以方便地设置项目之间的间距,不用再为margin头疼。支持row-gap和column-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网格布局从入门到精通——用网格思想重构网页,让二维布局不再头疼。