一篇文章掌握 Flexbox 布局的所有常用操作
📚 目录
基础概念
什么是 Flexbox?
Flexbox(弹性盒子布局)是 CSS3 引入的一种一维布局模型,用于在容器中分配空间和对齐项目。
核心概念
┌──────────────────────────────────────┐ ← flex container(容器)
│ 主轴起点 主轴终点 │
│ ↓ ↓ │
│ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ ← flex items(子项)
│ │ 1 │ │ 2 │ │ 3 │ │ 4 │ │
│ └─────┘ └─────┘ └─────┘ └─────┘ │
│ ←────────── 主轴(main axis)────→ │
│ ↑ │
│ 交叉轴(cross axis) │
└──────────────────────────────────────┘
关键术语:
- Flex Container(容器) :设置了
display: flex的父元素 - Flex Items(子项):容器的直接子元素
- 主轴(Main Axis) :默认水平方向,由
flex-direction决定 - 交叉轴(Cross Axis):垂直于主轴的方向
容器属性
1. display: flex
启用 Flexbox 布局
css
.container {
display: flex; /* 块级 flex 容器 */
/* 或 */
display: inline-flex; /* 行内 flex 容器 */
}
2. flex-direction
定义主轴方向
css
.container {
flex-direction: row; /* 默认,水平从左到右 */
flex-direction: row-reverse; /* 水平从右到左 */
flex-direction: column; /* 垂直从上到下 */
flex-direction: column-reverse; /* 垂直从下到上 */
}
可视化:
row: [1] [2] [3] [4] →
row-reverse: ← [4] [3] [2] [1]
column: [1]
[2]
[3]
[4]
↓
column-reverse: ↑
[4]
[3]
[2]
[1]
3. justify-content
主轴对齐方式(水平对齐,当 flex-direction 为 row 时)
css
.container {
justify-content: flex-start; /* 默认,起点对齐 */
justify-content: flex-end; /* 终点对齐 */
justify-content: center; /* 居中对齐 */
justify-content: space-between; /* 两端对齐,项目间距相等 */
justify-content: space-around; /* 每个项目两侧间距相等 */
justify-content: space-evenly; /* 所有间距完全相等 */
}
可视化:
flex-start: [1] [2] [3] |
flex-end: [1] [2] [3] |
center: [1] [2] [3] |
space-between: [1] [2] [3] |
space-around: [1] [2] [3] |
space-evenly: [1] [2] [3] |
4. align-items
交叉轴对齐方式(垂直对齐,当 flex-direction 为 row 时)
css
.container {
align-items: stretch; /* 默认,拉伸填充 */
align-items: flex-start; /* 起点对齐 */
align-items: flex-end; /* 终点对齐 */
align-items: center; /* 居中对齐 */
align-items: baseline; /* 基线对齐 */
}
可视化:
stretch: ┌─────┐ ┌─────┐ ┌─────┐
│ 1 │ │ 2 │ │ 3 │
│ │ │ │ │ │
└─────┘ └─────┘ └─────┘
flex-start: ┌─────┐ ┌─────┐ ┌─────┐
│ 1 │ │ 2 │ │ 3 │
└─────┘ └─────┘ └─────┘
center:
┌─────┐ ┌─────┐ ┌─────┐
│ 1 │ │ 2 │ │ 3 │
└─────┘ └─────┘ └─────┘
flex-end:
┌─────┐ ┌─────┐ ┌─────┐
│ 1 │ │ 2 │ │ 3 │
└─────┘ └─────┘ └─────┘
5. flex-wrap
是否换行
css
.container {
flex-wrap: nowrap; /* 默认,不换行 */
flex-wrap: wrap; /* 换行,第一行在上 */
flex-wrap: wrap-reverse; /* 换行,第一行在下 */
}
可视化:
nowrap: [1] [2] [3] [4] [5] [6] →(可能溢出)
wrap: [1] [2] [3] [4]
[5] [6]
wrap-reverse: [5] [6]
[1] [2] [3] [4]
6. align-content
多行对齐方式(仅在有多行时生效)
css
.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; /* 间距相等 */
}
7. gap(现代属性)
设置子项间距
css
.container {
display: flex;
gap: 20px; /* 所有方向 */
/* 或 */
row-gap: 20px; /* 行间距 */
column-gap: 10px; /* 列间距 */
}
子元素属性
1. flex-grow
放大比例(如何分配剩余空间)
css
.item {
flex-grow: 0; /* 默认,不放大 */
flex-grow: 1; /* 平分剩余空间 */
flex-grow: 2; /* 获得 2 倍空间 */
}
示例:
css
.item1 { flex-grow: 1; } /* 占 1 份 */
.item2 { flex-grow: 2; } /* 占 2 份 */
.item3 { flex-grow: 1; } /* 占 1 份 */
┌──────────────────────────────────────┐
│ [item1] │ [item2──────] │ [item3] │
│ 25% │ 50% │ 25% │
└──────────────────────────────────────┘
2. flex-shrink
缩小比例(空间不足时如何收缩)
css
.item {
flex-shrink: 1; /* 默认,会收缩 */
flex-shrink: 0; /* 不收缩 */
flex-shrink: 2; /* 2 倍收缩速度 */
}
3. flex-basis
项目的基础大小
css
.item {
flex-basis: auto; /* 默认,根据内容 */
flex-basis: 200px; /* 固定宽度 */
flex-basis: 30%; /* 百分比 */
}
4. flex(简写属性)⭐
最常用的简写
css
.item {
/* flex: flex-grow flex-shrink flex-basis */
flex: 0 1 auto; /* 默认值 */
flex: 1; /* flex: 1 1 0% */
flex: auto; /* flex: 1 1 auto */
flex: none; /* flex: 0 0 auto */
}
常用值:
css
/* 自动填充剩余空间 */
.item { flex: 1; }
/* 固定宽度,不收缩不放大 */
.item { flex: 0 0 200px; }
/* 根据内容,可放大可缩小 */
.item { flex: auto; }
5. align-self
单个项目的对齐方式(覆盖 align-items)
css
.item {
align-self: auto; /* 默认,继承 align-items */
align-self: flex-start;
align-self: flex-end;
align-self: center;
align-self: baseline;
align-self: stretch;
}
6. order
改变项目排列顺序
css
.item {
order: 0; /* 默认 */
order: -1; /* 提前 */
order: 1; /* 延后 */
}
示例:
css
.item1 { order: 2; }
.item2 { order: 1; }
.item3 { order: 3; }
HTML: [1] [2] [3]
显示: [2] [1] [3]
常见布局场景
1. 水平垂直居中 ⭐⭐⭐
css
.container {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
height: 100vh; /* 容器高度 */
}
html
<div class="container">
<div class="centered-item">完美居中</div>
</div>
2. 两端对齐布局
css
.header {
display: flex;
align-items: center;
justify-content: space-between;
}
html
<div class="header">
<div class="logo">Logo</div>
<nav class="menu">Menu</nav>
</div>
┌───────────────────────────────────┐
│ [Logo] [Menu] │
└───────────────────────────────────┘
3. 左侧固定,右侧自适应
css
.layout {
display: flex;
}
.sidebar {
flex: 0 0 250px; /* 固定宽度 250px */
}
.content {
flex: 1; /* 占满剩余空间 */
}
html
<div class="layout">
<aside class="sidebar">侧边栏</aside>
<main class="content">主内容</main>
</div>
┌─────────┬──────────────────────────┐
│ Sidebar │ Content (自适应) │
│ 250px │ │
└─────────┴──────────────────────────┘
4. 等分布局
css
.grid {
display: flex;
gap: 20px;
}
.grid-item {
flex: 1; /* 每个子项等宽 */
}
html
<div class="grid">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
</div>
┌──────────┬──────────┬──────────┐
│ 1 │ 2 │ 3 │
└──────────┴──────────┴──────────┘
5. 圣杯布局(Holy Grail)
css
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.header, .footer {
flex: 0 0 auto;
}
.main {
flex: 1;
display: flex;
}
.sidebar {
flex: 0 0 200px;
}
.content {
flex: 1;
}
html
<div class="container">
<header class="header">Header</header>
<div class="main">
<aside class="sidebar">Sidebar</aside>
<main class="content">Content</main>
</div>
<footer class="footer">Footer</footer>
</div>
┌──────────────────────────┐
│ Header │
├────────┬─────────────────┤
│ Side │ Content │
│ bar │ (自适应高度) │
├────────┴─────────────────┤
│ Footer │
└──────────────────────────┘
6. 卡片网格布局
css
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.card {
flex: 0 0 calc(33.333% - 14px); /* 3 列 */
}
/* 响应式 */
@media (max-width: 768px) {
.card {
flex: 0 0 calc(50% - 10px); /* 2 列 */
}
}
@media (max-width: 480px) {
.card {
flex: 0 0 100%; /* 1 列 */
}
}
7. 底部固定布局
css
.container {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.content {
flex: 1; /* 内容区自动填充 */
}
.footer {
flex: 0 0 auto;
}
┌──────────────────────────┐
│ Content │
│ │
│ (自动扩展) │
│ │
├──────────────────────────┤
│ Footer │ ← 始终在底部
└──────────────────────────┘
8. 导航栏布局
css
.navbar {
display: flex;
align-items: center;
padding: 0 20px;
}
.logo {
margin-right: auto; /* Logo 左侧,其他右侧 */
}
.nav-links {
display: flex;
gap: 20px;
}
html
<nav class="navbar">
<div class="logo">Logo</div>
<ul class="nav-links">
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
<button class="login">Login</button>
</nav>
┌─────────────────────────────────────────┐
│ [Logo] [Home][About][Contact][Login] │
└─────────────────────────────────────────┘
实战技巧
1. Auto Margin 技巧 ⭐⭐⭐
在 Flexbox 中,margin: auto 可以消耗所有剩余空间
推送到右侧
css
.container {
display: flex;
}
.item-left {
/* 正常布局 */
}
.item-right {
margin-left: auto; /* 推到最右边 */
}
html
<div class="container">
<div class="item-left">Left</div>
<div class="item-right">Right</div>
</div>
┌─────────────────────────────────────┐
│ [Left] [Right] │
└─────────────────────────────────────┘
水平垂直居中(单个元素)
css
.container {
display: flex;
}
.centered {
margin: auto; /* 完美居中 */
}
2. 最后一行左对齐
问题:使用 justify-content: space-between 时,最后一行会两端对齐
css
/* 方法 1:添加空白占位符 */
.grid::after {
content: '';
flex: auto;
}
/* 方法 2:使用 gap 代替 justify-content */
.grid {
display: flex;
flex-wrap: wrap;
gap: 20px;
}
.item {
flex: 0 0 calc(33.333% - 14px);
}
3. 溢出滚动
css
.container {
display: flex;
overflow-x: auto; /* 水平滚动 */
}
.item {
flex: 0 0 200px; /* 固定宽度,不收缩 */
}
4. 反转布局
css
/* HTML 顺序:A B C */
/* 显示顺序:C B A */
.container {
display: flex;
flex-direction: row-reverse;
}
/* 或使用 order */
.item-a { order: 3; }
.item-b { order: 2; }
.item-c { order: 1; }
5. 垂直居中多行文本
css
.container {
display: flex;
align-items: center;
min-height: 200px;
}
.text {
/* 多行文本也会垂直居中 */
}
6. 按钮组布局
css
.button-group {
display: flex;
gap: 10px;
}
/* 左对齐 */
.button-group.left {
justify-content: flex-start;
}
/* 右对齐 */
.button-group.right {
justify-content: flex-end;
}
/* 居中 */
.button-group.center {
justify-content: center;
}
7. 固定比例布局
css
/* 比例 2:3:1 */
.item1 { flex: 2; }
.item2 { flex: 3; }
.item3 { flex: 1; }
┌────┬─────────┬───┐
│ 2 │ 3 │ 1 │
└────┴─────────┴───┘
8. 响应式导航
css
.nav {
display: flex;
gap: 20px;
}
@media (max-width: 768px) {
.nav {
flex-direction: column; /* 垂直排列 */
}
}
最佳实践
1. ✅ 优先使用 flex 简写
css
/* ❌ 不推荐 */
.item {
flex-grow: 1;
flex-shrink: 1;
flex-basis: 0%;
}
/* ✅ 推荐 */
.item {
flex: 1;
}
2. ✅ 使用 gap 代替 margin
css
/* ❌ 老方法 */
.container {
display: flex;
}
.item {
margin-right: 20px;
}
.item:last-child {
margin-right: 0;
}
/* ✅ 新方法 */
.container {
display: flex;
gap: 20px;
}
3. ✅ 避免不必要的嵌套
css
/* ❌ 过度嵌套 */
.outer {
display: flex;
}
.middle {
display: flex;
flex: 1;
}
.inner {
display: flex;
}
/* ✅ 扁平化 */
.container {
display: flex;
}
4. ✅ 使用 min-width: 0 解决文本溢出
css
/* 问题:flex item 中长文本不换行 */
.item {
flex: 1;
min-width: 0; /* 允许收缩到 0 */
}
.text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
5. ✅ 考虑浏览器兼容性
css
/* 添加前缀(现代构建工具会自动处理) */
.container {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
6. ✅ 合理使用 align-items vs align-content
css
/* 单行对齐用 align-items */
.container {
display: flex;
align-items: center;
}
/* 多行对齐用 align-content */
.container {
display: flex;
flex-wrap: wrap;
align-content: center;
}
7. ✅ 防止内容撑大容器
css
.container {
display: flex;
}
.item {
flex: 1;
min-width: 0; /* 允许收缩 */
overflow: hidden; /* 裁剪溢出 */
}
快速参考表
容器属性速查
| 属性 | 作用 | 常用值 |
|---|---|---|
display |
启用 Flexbox | flex, inline-flex |
flex-direction |
主轴方向 | row, column |
justify-content |
主轴对齐 | center, space-between |
align-items |
交叉轴对齐 | center, stretch |
flex-wrap |
是否换行 | wrap, nowrap |
gap |
间距 | 20px, 1rem |
子元素属性速查
| 属性 | 作用 | 常用值 |
|---|---|---|
flex |
缩放比例 | 1, 0 0 200px |
align-self |
单独对齐 | center, flex-start |
order |
排列顺序 | 0, -1, 1 |
常用组合速查
| 场景 | CSS |
|---|---|
| 水平垂直居中 | display: flex; justify-content: center; align-items: center; |
| 两端对齐 | display: flex; justify-content: space-between; |
| 等分布局 | display: flex; .item { flex: 1; } |
| 固定+自适应 | .fixed { flex: 0 0 200px; } .auto { flex: 1; } |
| 底部固定 | display: flex; flex-direction: column; .content { flex: 1; } |
在线工具推荐
-
Flexbox Playground
- https://codepen.io/enxaneta/pen/adLPwv
- 交互式学习 Flexbox
-
Flexbox Froggy
-
CSS Tricks Guide
-
Flexbox Defense
总结
记住这 3 个核心概念:
display: flex- 启用 Flexbox- 主轴对齐 -
justify-content(水平) - 交叉轴对齐 -
align-items(垂直)
记住这 2 个常用技巧:
flex: 1- 自动填充空间margin: auto- 推送元素到边缘
记住这 1 个黄金法则:
先理解主轴和交叉轴,90% 的布局问题都能解决!
实战练习
试着用 Flexbox 实现以下布局:
- ✅ 登录页面(垂直水平居中的表单)
- ✅ 导航栏(Logo 左侧,菜单右侧)
- ✅ 卡片列表(3 列响应式网格)
- ✅ 个人中心页(左侧导航,右侧内容)
- ✅ 移动端底部标签栏