Flexbox 完全自学手册
前言:为什么是 Flexbox?
在 Flexbox 出现之前,我们布局主要依赖 display, position, float 这些属性,它们在处理一些简单的布局时还算得心应手,但一旦遇到垂直居中、等高列、按比例分配空间等复杂需求,就会变得非常繁琐,需要大量“奇技淫巧”(如负 margin、table hack 等)。
Flexbox(弹性盒子布局) 应运而生,它是一种一维布局模型,专门用来解决在容器中排列、对齐和分配空间的问题,它能极大地简化我们的布局代码,提高开发效率和可维护性。

第一章:核心概念
理解 Flexbox,首先要理解两个核心角色:
- Flex Container (弹性容器): 启用了
display: flex;或display: inline-flex;的父元素,它成为了弹性布局的上下文。 - Flex Items (弹性项目): Flex Container 的直接子元素,这些子元素会自动成为弹性项目,并遵循弹性布局的规则。
<div class="container"> <!-- 这是 Flex Container --> <div class="item">1</div> <div class="item">2</div> <div class="item">3</div> <!-- 这些是 Flex Items --> </div>
第二章:Flex Container 的属性
这些属性定义了整个弹性容器的布局方向、对齐方式和换行行为。
1 flex-direction - 主轴方向
这是最重要的属性,它决定了 Flex Item 的排列方向,主轴(Main Axis)和交叉轴(Cross Axis)的概念由此产生。
row(默认): 从左到右,水平排列。row-reverse: 从右到左,水平排列。column: 从上到下,垂直排列。column-reverse: 从下到上,垂直排列。
.container {
display: flex;
/* 水平排列,主轴是水平方向 */
flex-direction: row;
/* 垂直排列,主轴是垂直方向 */
/* flex-direction: column; */
}
2 flex-wrap - 换行
当 Flex Item 的总宽度超过容器宽度时,如何处理。

nowrap(默认): 不换行,所有 Item 挤在一行。wrap: 换行,第一行在上方,后续行在下方。wrap-reverse: 换行,第一行在下方,后续行在上方。
.container {
display: flex;
flex-wrap: wrap; /* 允许换行 */
}
3 justify-content - 主轴对齐
在主轴上,如何分配 Flex Item 之间的空白空间。
flex-start(默认): 从主轴起点开始排列。flex-end: 从主轴终点开始排列。center: 在主轴上居中排列。space-between: 空白空间均匀分布在 Item 之间,Item 之间没有间距。space-around: 空白空间均匀分布在 Item 的两侧,Item 之间的间距是两端间距的两倍。space-evenly: 空白空间均匀分布在所有 Item 之间,包括 Item 的两侧,间距完全相等。
4 align-items - 交叉轴对齐
在交叉轴上,如何对齐所有 Flex Item。
stretch(默认): Item 没有设置高度或高度为auto,则拉伸至与容器同高。flex-start: 从交叉轴起点对齐。flex-end: 从交叉轴终点对齐。center: 在交叉轴上居中对齐。baseline: 以 Item 的第一行文字的基线对齐。
5 align-content - 多行交叉轴对齐
当 flex-wrap: wrap 且 Item 换行后,这个属性用于控制多行在交叉轴上的对齐方式。(仅对多行有效)
stretch(默认): 行被拉伸以填充容器。flex-start: 行从交叉轴起点开始排列。flex-end: 行从交叉轴终点开始排列。center: 行在交叉轴上居中排列。space-between: 行之间空白空间均匀分布。space-around: 行两侧和行之间空白空间均匀分布。
第三章:Flex Items 的属性
这些属性用于控制单个弹性项目的表现。

1 flex-grow - 放大比例
定义项目的放大系数,如果容器有剩余空间,flex-grow 决定了 Item 如何分配这些空间。
- 值为
0(默认): 不放大。 - 值为正数 (如
1,2): 按比例放大,所有 Item 的flex-grow值相加,得到一个总和,每个 Item 分到的空间是(自身的值 / 总和) * 剩余空间。
实战:等宽列 让所有 Item 平分容器的宽度。
.item {
flex-grow: 1; /* 所有 Item 都设置为 1,它们会平分剩余空间 */
}
2 flex-shrink - 缩小比例
定义项目的缩小系数,当容器空间不足时,flex-shrink 决定了 Item 如何被压缩。
- 值为
1(默认): 允许缩小。 - 值为
0: 不允许缩小。 - 值为正数: 按比例缩小,计算逻辑类似
flex-grow,但基于“超出空间”。
3 flex-basis - 基准尺寸
在分配剩余空间或计算超出空间之前,Item 的初始尺寸。
auto(默认): Item 的尺寸由其内容决定(width或height)。0: Item 的初始尺寸为 0,然后根据flex-grow和flex-shrink来分配空间。- 具体值 (如
200px,20%): Item 的初始尺寸为该固定值。
4 flex - 简写属性
这是最常用、最强大的简写属性,它合并了 flex-grow, flex-shrink, 和 flex-basis。
语法:flex: <flex-grow> <flex-shrink> <flex-basis>;
常用组合:
-
flex: 1 1 0;或flex: 1;(最推荐)flex-grow: 1(可放大)flex-shrink: 1(可缩小)flex-basis: 0(初始尺寸为0,意味着它会完全根据可用空间来分配)- 效果: 创建一个可伸缩的、填充可用空间的 Item。
-
flex: 0 0 auto;或flex: initial;(默认值)flex-grow: 0(不放大)flex-shrink: 1(可缩小)flex-basis: auto(基于内容尺寸)- 效果: 表现和未设置
display: flex时一样,按内容大小显示,空间不足时会缩小。
-
flex: 0 1 auto;flex-grow: 0(不放大)flex-shrink: 1(可缩小)flex-basis: auto(基于内容尺寸)- 效果: 常用于固定宽度的侧边栏,主内容区可以滚动。
5 align-self - 单项交叉轴对齐
允许单个 Item 覆盖容器的 align-items 属性。
auto(默认): 继承父容器的align-items值。flex-start,flex-end,center,baseline,stretch: 与align-items的值相同。
.item-1 {
align-self: flex-start; /* 这个 Item 从交叉轴顶部对齐 */
}
.item-2 {
align-self: center; /* 这个 Item 在交叉轴上居中 */
}
第四章:经典实战案例
经典三栏布局 (侧边栏 + 主内容 + 侧边栏)
目标: 左右固定宽度,中间内容自适应。
<div class="page"> <aside class="sidebar">Left</aside> <main class="content">Main Content</main> <aside class="sidebar">Right</aside> </div>
.page {
display: flex;
height: 100vh; /* 让容器占满整个视口高度 */
}
.sidebar {
width: 200px; /* 固定宽度 */
background: #f0f0f0;
flex-shrink: 0; /* 重要:防止缩小 */
}
.content {
flex: 1; /* 核心:flex: 1 1 0 的简写,占据所有剩余空间 */
background: #e0e0e0;
padding: 20px;
}
垂直水平居中
目标: 将一个未知大小的元素完美居中。
<div class="center-box">
<div class="content">
<h2>我是居中的内容</h2>
<p>无论内容多少,我都能完美居中。</p>
</div>
</div>
.center-box {
display: flex;
justify-content: center; /* 主轴(水平)居中 */
align-items: center; /* 交叉轴(垂直)居中 */
height: 400px;
border: 2px solid #ccc;
}
.content {
/* 不需要任何 width/height 或 margin */
background: #f9f9f9;
padding: 20px;
}
导航栏
目标: 创建一个自适应的导航栏,链接均匀分布。
<nav class="navbar"> <a href="#">Home</a> <a href="#">About</a> <a href="#">Services</a> <a href="#">Contact</a> </nav>
.navbar {
display: flex;
justify-content: space-between; /* 链接均匀分布 */
background: #333;
padding: 0 20px;
}
.navbar a {
color: white;
text-decoration: none;
padding: 15px 0; /* 垂直方向有间距 */
}
第五章:常见问题与技巧
-
min-width和max-width与flex冲突- 问题: 当
flex-basis设置为0%时,Item 的内容宽度超过了其父容器的min-width,布局可能会崩溃。 - 解决方案: 在设置了
flex: 1的 Item 上,也设置一个min-width: 0;,这会强制 Item 的flex-basis为 0,并允许其内容缩小。
.content { flex: 1; min-width: 0; /* 解决长文本或图片撑破容器的问题 */ } - 问题: 当
-
flex的顺序控制order属性可以改变 Item 的渲染顺序,数值越小,越排在前面,默认为0。
.item:nth-child(2) { order: -1; /* 将第二个 Item 移到最前面 */ } -
什么时候用 Flexbox,什么时候用 Grid?
- Flexbox (一维): 适合线性布局,即一行或一列,导航栏、表单元素、卡片列表、垂直居中,它的核心是对齐和分配空间。
- Grid (二维): 适合二维布局,即同时处理行和列,整个页面的布局、复杂的仪表盘、图片画廊,它的核心是网格结构。
简单记: Flexbox 处理项目,Grid 处理区域。
第六章:总结与进阶
核心要点回顾
- 主角:
display: flex定义容器,其子元素成为项目。 - 方向:
flex-direction决定主轴方向(行或列)。 - 对齐:
justify-content控制主轴上的对齐。align-items控制交叉轴上的对齐。align-self控制单个项目的交叉轴对齐。
- 伸缩:
flex-grow决定如何分配剩余空间。flex-shrink决定如何压缩空间。flex: 1是创建自适应空间的利器。
- 换行:
flex-wrap控制项目是否换行。
进阶学习
- CSS Grid: 学习 Grid 布局,与 Flexbox 结合使用,可以解决几乎所有现代布局问题。
- 响应式设计: 结合媒体查询,使用 Flexbox 创建在不同屏幕尺寸下都能完美适配的布局。
- Flexbox 的浏览器兼容性: 现代浏览器对 Flexbox 支持非常好,但如果你需要支持非常旧的浏览器(如 IE11),需要注意一些兼容性问题(如
flex的写法)。
实践是掌握 Flexbox 的唯一途径。 打开你的代码编辑器,亲手敲出上面的每一个例子,然后尝试修改它们的属性,观察布局的变化,当你能熟练运用 Flexbox 解决各种布局难题时,你就真正掌握了它,祝你学习顺利!