CSS: Flexbox 容器属性
Flexbox(弹性布局)是一种一维布局模型,可以让你轻松控制元素在主轴和交叉轴上的排列方式。它是现代网页布局中最常用的技术之一。
1. 什么是 Flexbox?
💡 Flexbox 的核心思想: 记住一句话——"容器控制整体排列,项目控制自身行为"。容器的
flex-direction 决定了项目的排列方向,justify-content 决定主轴对齐,align-items 决定交叉轴对齐。
📌 默认值:
flex-direction 默认为 row(水平排列),从右往左或垂直排列需要显式设置。column 在移动端布局中非常常用——导航栏从水平变成垂直就是通过改变这个属性实现的。
Flexbox 是 Flexible Box 的缩写,意为"弹性布局"。通过设置 display: flex,一个元素就变成了 flex 容器,它的所有子元素自动变成 flex 项目。Flexbox 提供了一套强大的属性来控制项目的排列、对齐和空间分配。
(1) Flexbox 容器属性速查表
| 属性 | 常用值 | 作用 |
|---|---|---|
display |
flex, inline-flex |
启用弹性布局(容器) |
flex-direction |
row, row-reverse, column, column-reverse |
主轴方向(项目排列方向) |
flex-wrap |
nowrap, wrap, wrap-reverse |
项目是否换行 |
justify-content |
flex-start, flex-end, center, space-between, space-around, space-evenly |
主轴对齐方式 |
align-items |
stretch, flex-start, flex-end, center, baseline |
交叉轴对齐(单行) |
align-content |
stretch, flex-start, flex-end, center, space-between, space-around |
交叉轴对齐(多行) |
gap |
10px, 1rem, 20px 10px |
项目间距(行+列) |
浏览器兼容性:几乎所有现代浏览器(Chrome、Firefox、Edge、Safari)都已全面支持 Flexbox。
2. 容器与项目
▶ 示例
HTML
<style>
.container {
display: flex; /* 启用弹性布局 */
}
.container-item {
background: #e8f4f8;
border: 1px solid #3498db;
padding: 16px;
margin: 4px;
border-radius: 4px;
text-align: center;
}
</style>
<div class="container">
<div class="container-item">Container item</div>
<div class="container-item">Container item</div>
<div class="container-item">Container item</div>
</div>
一旦启用 flex:
- 容器(flex container):
- 子元素将沿主轴排列
float、clear、vertical-align对子元素失效
- 项目(flex item):容器的直接子元素
(1) 主轴(Main Axis)和交叉轴(Cross Axis)
Flexbox 有两条隐形的参考轴线:
- 主轴(Main Axis):默认水平方向(从左到右)
- 交叉轴(Cross Axis):默认垂直方向(从上到下)
通过 flex-direction 可以互换主轴和交叉轴的方向。
3. 容器属性
(1) 1. display:启用 flex
▶ 示例
HTML
<style>
.container {
display: flex; /* 块级 flex 容器 */
/* display: inline-flex; */ /* 行内 flex 容器 */
}
.container-item {
background: #e8f4f8;
border: 1px solid #3498db;
padding: 16px;
margin: 4px;
border-radius: 4px;
text-align: center;
}
</style>
<div class="container">
<div class="container-item">Container item</div>
<div class="container-item">Container item</div>
<div class="container-item">Container item</div>
</div>
(2) 2. flex-direction:主轴方向
控制项目的排列方向:
▶ 示例
HTML
<style>
.container {
flex-direction: row; /* 默认,水平从左到右 */
flex-direction: row-reverse; /* 水平从右到左 */
flex-direction: column; /* 垂直从上到下 */
flex-direction: column-reverse; /* 垂直从下到上 */
}
</style>
<div class="container">容器元素,内部包含其他子元素</div>
(3) 3. flex-wrap:换行控制
控制项目是否换行:
▶ 示例
HTML
<style>
.container {
flex-wrap: nowrap; /* 默认,不换行,会压缩 */
flex-wrap: wrap; /* 换行 */
flex-wrap: wrap-reverse; /* 反向换行 */
}
</style>
<div class="container">容器元素,内部包含其他子元素</div>
(4) 4. flex-flow:方向与换行简写
flex-direction 和 flex-wrap 的简写:
▶ 示例
HTML
<style>
.container {
flex-flow: row wrap; /* 水平排列,允许换行 */
flex-flow: column nowrap; /* 垂直排列,不换行(默认) */
}
</style>
<div class="container">容器元素,内部包含其他子元素</div>
<span class="demo-row">行方向</span>
<span class="demo-column">列方向</span>
(5) 5. justify-content:主轴对齐
控制项目在主轴方向上的对齐方式:
▶ 示例
HTML
<style>
.container {
justify-content: flex-start; /* 默认,起始对齐 */
justify-content: flex-end; /* 结束对齐 */
justify-content: center; /* 居中对齐 */
justify-content: space-between; /* 两端对齐,项目之间间距相等 */
justify-content: space-around; /* 每个项目两侧间距相等 */
justify-content: space-evenly; /* 项目和边缘间距相等 */
}
</style>
<div class="container">容器元素,内部包含其他子元素</div>
(6) 6. align-items:交叉轴对齐
控制项目在交叉轴方向上的对齐方式:
▶ 示例
HTML
<style>
.container {
align-items: stretch; /* 默认,拉伸填满 */
align-items: flex-start; /* 起始对齐 */
align-items: flex-end; /* 结束对齐 */
align-items: center; /* 居中对齐 */
align-items: baseline; /* 文字基线对齐 */
}
</style>
<div class="container">容器元素,内部包含其他子元素</div>
(7) 7. align-content:多行对齐
⚠️ align-content vs align-items:
align-content 只有在多行时才生效,它控制的是行与行之间的间距。而 align-items 控制的是每行内部项目的对齐方式。这两个属性经常被混淆。
只在项目换行(flex-wrap: wrap)时有效,控制多行在交叉轴上的对齐:
▶ 示例
HTML
<style>
.container {
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; /* 等距分布 */
}
</style>
<div class="container">容器元素,内部包含其他子元素</div>
(8) 8. gap:项目间距
设置项目之间的间距(容器属性,作用于项目之间,不影响容器边缘):
▶ 示例
HTML
<style>
.container {
gap: 20px; /* 行和列间距都是20px */
row-gap: 10px; /* 行间距 */
column-gap: 15px; /* 列间距 */
}
</style>
<div class="container">容器元素,内部包含其他子元素</div>
4. 完整示例
▶ 示例
HTML
<style>
.flex-container {
display: flex;
flex-flow: row wrap;
justify-content: space-between;
align-items: center;
gap: 20px;
padding: 20px;
background: #f0f0f0;
min-height: 300px;
}
.flex-item {
width: 150px;
height: 150px;
background: #3498db;
color: white;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8px;
}
.flex-item-item {
background: #e8f4f8;
border: 1px solid #3498db;
padding: 16px;
margin: 4px;
border-radius: 4px;
text-align: center;
}
</style>
<div class="flex-item">
<div class="flex-item-item">Flex item item</div>
<div class="flex-item-item">Flex item item</div>
<div class="flex-item-item">Flex item item</div>
</div>
❓ 常见问题
Q flex-direction: column 后 justify-content 还是水平方向吗?
A 不是。flex-direction 改变主轴方向,justify-content 始终沿主轴排列。
row 时主轴是水平,column 时主轴变为垂直。记住:flex-direction 决定了"哪个方向是主轴"。Q flex-wrap 什么时候用?
A 当容器宽度不够,子元素放不下时,默认(nowrap)会压缩子元素。设置
flex-wrap: wrap 后,放不下的子元素会自动换行到下一行。这在响应式布局中非常常见。Q align-items 和 align-content 有什么区别?
A align-items 控制单行内项目的对齐方式(每行内部),align-content 控制多行之间的空间分配(只有多行时才生效)。单行时 align-content 无效。
5. 实战案例:纯CSS导航栏
这个案例展示了如何用Flexbox实现一个响应式导航栏:
▶ 示例
HTML
📖 仅展示
<style>
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
background: #2c3e50;
color: white;
height: 60px;
}
.navbar-logo {
font-size: 24px;
font-weight: bold;
}
.navbar-menu {
display: flex;
gap: 20px;
list-style: none;
margin: 0;
padding: 0;
}
.navbar-menu a {
color: white;
text-decoration: none;
padding: 10px 15px;
border-radius: 4px;
transition: background 0.3s ease;
}
.navbar-menu a:hover {
background: rgba(255,255,255,0.1);
}
.navbar-burger {
display: none;
flex-direction: column;
gap: 5px;
cursor: pointer;
}
.navbar-burger span {
width: 25px;
height: 3px;
background: white;
border-radius: 2px;
}
@media (max-width: 768px) {
.navbar-menu {
display: none;
}
.navbar-burger {
display: flex;
}
}
</style>
<nav class="navbar">
<div class="navbar-logo">Web-Tutorial</div>
<ul class="navbar-menu">
<li><a href="#">首页</a></li>
<li><a href="#">教程</a></li>
<li><a href="#">关于</a></li>
<li><a href="#">联系</a></li>
</ul>
<div class="navbar-burger">
<span></span>
<span></span>
<span></span>
</div>
</nav>
💡 实现原理: 使用
display: flex + justify-content: space-between 实现Logo和菜单的左右分布。移动端通过媒体查询隐藏菜单,显示汉堡按钮。
📖 小节
- Flexbox 容器属性控制的是"整体"行为——项目如何排列、是否换行、如何在主轴上对齐、在交叉轴上对齐
- 记住一个口诀:
justify-content控制主轴方向的对齐,align-items控制交叉轴方向的对齐 - 如果
flex-direction变了,这两者的作用方向也会互换
📝 作业
基础题
- 创建一个 flex 容器,内含 5 个子项目。分别尝试
flex-direction的四个值,观察排列方向的变化。 - 继续使用上面的容器,演示
justify-content的 6 种取值效果(每个值截一张图对比)。
进阶题
- 设置
flex-wrap: wrap,让项目排满一行后自动换行,再给容器设置align-content的不同值,观察多行对齐的效果。 - 使用
gap属性设置项目间距,与使用margin设置间距进行对比,体会 gap 的便利性。
挑战题
- 创建一个响应式导航栏,要求:
- 桌面端:Logo在左,菜单在右,水平排列
- 移动端:Logo在左,汉堡按钮在右,菜单隐藏
- 创建一个卡片列表,使用
justify-content: space-between让卡片均匀分布,最后一行左对齐。