Flex布局精通
作者:海川,发表于:2026年1月24日 07:30:00
全面掌握Flex布局
一、Flex 基础概念
1. 什么是 Flex?
- Flexible Box Layout,灵活的盒子布局
- 是CSS3提供的一种强大的一维布局方案
- 相比浮动、定位等传统布局方式,Flex具有更好的灵活性和易用性
- 广泛应用于现代Web开发中,特别是响应式设计
2. Flex 相比传统布局的优势
- ✅ 自适应性强,能自动调整子元素宽度/高度来填充容器
- ✅ 对齐方式灵活,轻松实现水平、竖直、中心对齐等
- ✅ 排序方便,可通过order属性改变元素顺序,不影响HTML结构
- ✅ 代码简洁,相比Grid更易上手
- ✅ 浏览器兼容性好
3. Flex 布局的两个角色
- Flex容器:使用
display: flex的元素 - Flex项目:容器的子元素
- 容器属性用于控制项目如何分布排列,项目属性用于控制自身的大小和位置
4. Flex 与 Grid 的区别
| 特性 | Flex | Grid |
|---|---|---|
| 布局维度 | 一维布局 | 二维布局 |
| 排列方式 | 按行或列线性排列 | 按行列网格排列 |
| 控制方式 | 项目被动适应容器 | 显式定义行列,项目放在网格中 |
| 用途 | 导航栏、工具栏、列表、卡片排列 | 复杂网格、仪表盘、页面布局 |
| 学习成本 | 低,容易上手 | 高,概念多 |
| 主要属性 | justify-content、align-items、flex | grid-template-rows、grid-template-columns、grid-area |
| 适配对齐 | 主要用于单个方向的对齐分布 | 同时控制行列对齐 |
选择建议:
- ✅ 使用Flex:组件内部布局、导航、列表、一维排列
- ✅ 使用Grid:整体页面布局、复杂多行多列结构
- 💡 实际应用:通常将Flex和Grid结合使用,Grid做整体布局,Flex做细节排列
二、容器属性
1. display: flex
将元素设置为Flex容器,其子元素自动成为Flex项目。
.container {
display: flex; /* 块级Flex容器 */
/* display: inline-flex; */ /* 行内Flex容器 */
}
2. flex-direction - 主轴方向
定义主轴方向,即项目的排列方向。
| 属性值 | 说明 |
|---|---|
row | 默认值,从左到右排列 |
row-reverse | 从右到左排列 |
column | 从上到下排列 |
column-reverse | 从下到上排列 |
.container {
display: flex;
flex-direction: column; /* 纵向排列 */
}
3. flex-wrap - 换行处理
定义项目是否换行,以及换行方向。
| 属性值 | 说明 |
|---|---|
nowrap | 默认值,不换行 |
wrap | 换行,新行在下方 |
wrap-reverse | 换行,新行在上方 |
.container {
display: flex;
flex-wrap: wrap; /* 项目超出宽度时换行 */
}
4. flex-flow - 简写属性
flex-flow是flex-direction和flex-wrap的简写。
.container {
display: flex;
flex-flow: row wrap; /* 先写direction,再写wrap */
}
5. justify-content - 主轴对齐
控制项目在主轴方向上的对齐方式。
| 属性值 | 说明 |
|---|---|
flex-start | 默认值,左对齐(或上对齐) |
flex-end | 右对齐(或下对齐) |
center | 中心对齐 |
space-between | 两端对齐,项目间间距相等 |
space-around | 项目两侧间距相等(外边距是内间距一半) |
space-evenly | 项目间间距、边界间距都相等 |
.container {
display: flex;
justify-content: space-between; /* 两端对齐 */
}
6. align-items - 交叉轴对齐(单行)
控制项目在交叉轴方向上的对齐方式(所有项目)。
| 属性值 | 说明 |
|---|---|
flex-start | 默认值,顶部对齐 |
flex-end | 底部对齐 |
center | 中心对齐 |
stretch | 拉伸,填满容器高度 |
baseline | 基线对齐 |
.container {
display: flex;
align-items: center; /* 垂直居中 */
height: 200px;
}
7. align-content - 交叉轴对齐(多行)
当有多行项目时,控制各行在交叉轴上的分布方式。
| 属性值 | 说明 |
|---|---|
flex-start | 默认值,顶部对齐 |
flex-end | 底部对齐 |
center | 中心对齐 |
space-between | 两端对齐,行间间距相等 |
space-around | 行两侧间距相等 |
space-evenly | 行间间距、边界距离都相等 |
stretch | 拉伸,填满容器高度 |
.container {
display: flex;
flex-wrap: wrap;
align-content: space-between; /* 多行间距相等 */
height: 400px;
}
8. gap - 项目间距
设置项目之间的间距(CSS最新属性,兼容性好)。
.container {
display: flex;
gap: 10px; /* 所有方向间距10px */
/* gap: 10px 20px; */ /* 行间距10px,列间距20px */
}
容器属性速查表
| 属性 | 用途 | 常见值 |
|---|---|---|
flex-direction | 主轴方向 | row、column |
flex-wrap | 换行方式 | nowrap、wrap |
justify-content | 主轴对齐 | center、space-between、center |
align-items | 交叉轴对齐(单行) | center、stretch |
align-content | 交叉轴对齐(多行) | center、space-between |
gap | 项目间距 | 10px、10px 20px |
三、项目属性
1. flex - 伸缩综合属性
flex是flex-grow、flex-shrink和flex-basis的简写,是设置项目尺寸的最重要属性。
.item {
/* flex: flex-grow flex-shrink flex-basis; */
flex: 1 1 0%; /* 默认值 */
flex: 1; /* 等同于 flex: 1 1 0% */
}
2. flex-grow - 伸缩比例
定义项目的伸展能力,即如何分配容器的剩余空间。
- 默认值:0(不伸展)
- 当容器有剩余空间时,按比例分配给各项目
- 所有项目的
flex-grow之和 > 1时,项目会按比例分配剩余空间
.item1 {
flex-grow: 1;
}
.item2 {
flex-grow: 2; /* 比item1多占2倍的剩余空间 */
}
3. flex-shrink - 收缩比例
定义项目的收缩能力,即容器空间不足时如何收缩。
- 默认值:1(收缩)
- 当容器空间不足时,按比例收缩各项目
- 值为0表示不收缩
.item {
flex-shrink: 1; /* 默认,空间不足时收缩 */
/* flex-shrink: 0; */ /* 不收缩,保持原始宽度 */
}
4. flex-basis - 基础尺寸
定义项目分配剩余空间之前的基础大小。
- 默认值:auto(自动计算)
- 常用值:像素长度、百分比、auto
.item {
flex-basis: 200px; /* 基础宽度200px */
/* flex-basis: 50%; */ /* 基础宽度50% */
/* flex-basis: auto; */ /* 自动计算 */
}
5. align-self - 单个项目对齐
用于覆盖容器的align-items,控制单个项目的交叉轴对齐。
| 属性值 | 说明 |
|---|---|
auto | 默认值,继承容器 |
flex-start | 顶部对齐 |
flex-end | 底部对齐 |
center | 中心对齐 |
stretch | 拉伸 |
baseline | 基线对齐 |
.item {
align-self: flex-end; /* 该项目底部对齐,覆盖容器设置 */
}
6. order - 排序
改变项目在容器中的排列顺序,不影响HTML结构。
- 默认值:0
- 值越小越靠前
- 可以为负数
.item1 {
order: 3;
}
.item2 {
order: 1; /* item2会排在item1前面 */
}
.item3 {
order: 2;
}
项目属性速查表
| 属性 | 用途 | 常见值 |
|---|---|---|
flex | 伸缩综合属性 | 1、0、1 0 200px |
flex-grow | 伸展比例 | 0、1、2 |
flex-shrink | 收缩比例 | 0、1 |
flex-basis | 基础尺寸 | auto、200px、50% |
align-self | 单个项目交叉轴对齐 | center、flex-end |
order | 排序 | 0、1、-1 |
四、实用案例
1. 水平居中布局
<div class="container">
<div class="item">居中内容</div>
</div>
.container {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 200px;
}
2. 导航栏布局
<nav class="navbar">
<div class="logo">Logo</div>
<div class="menu">
<a href="#">首页</a>
<a href="#">产品</a>
<a href="#">关于</a>
</div>
<div class="user">登录</div>
</nav>
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 20px;
background: #333;
color: white;
}
.menu {
display: flex;
gap: 20px;
}
.menu a {
color: white;
text-decoration: none;
}
3. 两栏布局(侧边栏 + 主内容)
<div class="layout">
<aside class="sidebar">侧边栏</aside>
<main class="content">主内容</main>
</div>
.layout {
display: flex;
height: 100vh;
}
.sidebar {
flex: 0 0 250px; /* 不伸不缩,宽度250px */
background: #f0f0f0;
}
.content {
flex: 1; /* 剩余空间全部分配给主内容 */
padding: 20px;
}
4. 响应式卡片网格
<div class="grid">
<div class="card">卡片1</div>
<div class="card">卡片2</div>
<div class="card">卡片3</div>
<div class="card">卡片4</div>
</div>
.grid {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.card {
flex: 1 1 calc(33.333% - 14px); /* 3列布局 */
min-width: 200px; /* 最小宽度 */
padding: 20px;
background: white;
border: 1px solid #ddd;
}
/* 手机端:1列 */
@media (max-width: 768px) {
.card {
flex: 1 1 100%;
}
}
5. 垂直居中弹框
<div class="modal-overlay">
<div class="modal">弹框内容</div>
</div>
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
}
.modal {
background: white;
width: 400px;
padding: 30px;
border-radius: 8px;
}
6. 底部自适应布局
<div class="app">
<header>头部</header>
<main>主要内容</main>
<footer>底部</footer>
</div>
.app {
display: flex;
flex-direction: column;
height: 100vh;
}
header {
flex: 0 0 60px; /* 高度固定60px */
background: #333;
}
main {
flex: 1; /* 占用剩余空间 */
overflow-y: auto;
}
footer {
flex: 0 0 40px; /* 高度固定40px */
background: #f0f0f0;
}
五、Flex 与 Grid 的对比
| 特性 | Flex | Grid |
|---|---|---|
| 维度 | 一维 | 二维 |
| 用途 | 行或列排列 | 复杂网格布局 |
| 学习成本 | 低 | 高 |
| 浏览器兼容性 | 极好 | 很好 |
| 推荐场景 | 导航栏、列表、简单布局 | 复杂网格、仪表盘 |
六、常见问题 & 最佳实践
1. flex:1 的真实含义
.item {
flex: 1;
/* 等同于 */
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%; /* 关键:基础尺寸为0% */
}
设置flex-basis: 0%的好处是:项目的初始宽度为0,项目不会因为内容多少而影响基础宽度,所有剩余空间都会按比例分配。
2. min-width 的坑
.container {
display: flex;
}
.item {
flex: 1;
min-width: 0; /* 重要!避免文本溢出 */
}
Flex项目默认的min-width: auto会导致内容溢出,设置min-width: 0可以让项目正常收缩。
3. 项目宽度处理
/* ✅ 推荐:显式设置flex-basis */
.item {
flex: 0 0 200px; /* 宽度200px,不伸不缩 */
}
/* ❌ 不推荐:同时设置width和flex-basis */
.item {
width: 200px;
flex: 1; /* 冲突 */
}
4. 文本截断
.item {
flex: 1;
min-width: 0; /* 必须 */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
5. 不等分布局
<div class="container">
<div class="left">左边固定宽度</div>
<div class="right">右边自适应</div>
</div>
.container {
display: flex;
}
.left {
flex: 0 0 200px; /* 固定宽度 */
}
.right {
flex: 1; /* 自适应剩余空间 */
}
七、浏览器兼容性
Flex布局在现代浏览器中兼容性极好:
- Chrome 29+
- Firefox 22+
- Safari 9+
- IE 11(部分支持,不支持flex-grow在auto宽度下的计算)
- Edge 全支持
对于需要兼容IE10的项目,可以使用display: -ms-flexbox等前缀。
八、调试技巧
1. 使用浏览器开发者工具
在Chrome/Firefox中,当选中Flex容器时,会自动显示Flex布局的可视化网格,帮助理解项目分布情况。
2. 常用的调试属性
.container {
border: 1px solid red; /* 显示容器边界 */
display: flex;
}
.item {
border: 1px solid blue; /* 显示项目边界 */
background: rgba(0, 0, 255, 0.1);
}
3. 检查溢出问题
/* 查看是否有内容溢出 */
.item {
overflow: visible; /* 改成auto或hidden查看 */
}