Flexbox 概述
Flexbox(Flexible Box Layout)是CSS3中的一种一维布局模型,专门用于在容器中沿一个方向(行或列)排列和分配空间。它解决了传统布局方式中垂直居中、等分布局、动态宽度等常见难题。
Flexbox最大的优势在于它能够动态地分配和调整元素的空间,即使元素的大小未知或会动态变化。这使得它成为构建响应式组件的理想选择。
Flexbox 适合一维布局(单行或单列),CSS Grid 适合二维布局(行列同时控制)。实际项目中,两者配合使用效果最佳。
Flex 容器属性
通过在父元素上设置 display: flex 或 display: inline-flex,即可将该元素变为Flex容器,其直接子元素自动成为Flex项目。
flex-direction
定义主轴方向,决定Flex项目如何排列。
.flex-row {
display: flex;
flex-direction: row; /* 默认:从左到右 */
}
.flex-row-reverse {
display: flex;
flex-direction: row-reverse; /* 从右到左 */
}
.flex-column {
display: flex;
flex-direction: column; /* 从上到下 */
}
.flex-column-reverse {
display: flex;
flex-direction: column-reverse; /* 从下到上 */
}
justify-content
控制Flex项目在主轴方向上的对齐方式。
| 值 | 效果 |
|---|---|
flex-start |
项目靠主轴起点对齐(默认) |
flex-end |
项目靠主轴终点对齐 |
center |
项目在主轴上居中 |
space-between |
两端对齐,项目之间等间距 |
space-around |
每个项目两侧有相等间距 |
space-evenly |
所有间距完全相等 |
align-items
控制Flex项目在交叉轴方向上的对齐方式。
.flex-container {
display: flex;
align-items: stretch; /* 默认:拉伸填满容器高度 */
/* align-items: flex-start; 靠交叉轴起点 */
/* align-items: flex-end; 靠交叉轴终点 */
/* align-items: center; 交叉轴居中 */
/* align-items: baseline; 基线对齐 */
}
flex-wrap
控制Flex项目是否换行。
.no-wrap {
display: flex;
flex-wrap: nowrap; /* 默认:不换行,项目可能溢出 */
}
.wrap {
display: flex;
flex-wrap: wrap; /* 允许换行 */
}
.wrap-reverse {
display: flex;
flex-wrap: wrap-reverse; /* 反向换行 */
}
gap
控制Flex项目之间的间距,比使用 margin 更干净。
.flex-gap {
display: flex;
flex-wrap: wrap;
gap: 16px; /* 行和列都是16px */
}
/* 分别设置行距和列距 */
.flex-gap-xy {
display: flex;
flex-wrap: wrap;
row-gap: 12px; /* 行间距 */
column-gap: 24px; /* 列间距 */
}
Flex 项目属性
这些属性应用在Flex容器的直接子元素(项目)上。
flex-grow, flex-shrink, flex-basis
.item {
flex-grow: 0; /* 默认:不放大。设为1则占据剩余空间 */
flex-shrink: 1; /* 默认:允许缩小。设为0则不缩小 */
flex-basis: auto; /* 默认:根据内容或width确定初始大小 */
}
/* 简写 */
.item {
flex: 0 1 auto; /* 默认值:grow shrink basis */
}
/* 常用模式 */
.item-auto {
flex: 1; /* flex: 1 1 0% — 等分剩余空间 */
}
.item-fixed {
flex: 0 0 200px; /* 固定宽度200px,不放大不缩小 */
}
.item-grow-only {
flex: 1 0 auto; /* 可以放大,但不会缩小 */
}
align-self
允许单个项目覆盖容器的 align-items 设置。
.container {
display: flex;
align-items: center; /* 所有项目居中 */
}
.special-item {
align-self: flex-end; /* 特殊项目靠底部对齐 */
}
.tall-item {
align-self: stretch; /* 拉伸到容器高度 */
}
order
控制Flex项目的视觉排列顺序(不影响DOM顺序)。
/* 默认所有项目 order 为 0,按DOM顺序排列 */
.item-1 { order: 3; } /* 排到最右边/下边 */
.item-2 { order: 1; }
.item-3 { order: 2; }
.item-4 { order: 0; } /* 默认位置,排到最左边/上边 */
/* 移动端调整顺序 */
@media (max-width: 768px) {
.sidebar { order: 2; } /* 移动端侧边栏移到主内容下方 */
.main { order: 1; }
}
常见Flexbox布局模式
导航栏
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
height: 60px;
}
.nav-brand {
font-size: 1.25rem;
font-weight: 700;
}
.nav-links {
display: flex;
gap: 24px;
list-style: none;
}
.nav-actions {
display: flex;
gap: 12px;
align-items: center;
}
卡片网格
.card-grid {
display: flex;
flex-wrap: wrap;
gap: 24px;
}
.card {
flex: 1 1 300px; /* 最小300px,可放大 */
max-width: 400px;
padding: 24px;
border: 1px solid var(--border);
border-radius: 8px;
background: var(--bg-card);
}
完美居中
/* 最简洁的居中方案 */
.center {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
/* 水平居中 */
.horizontal-center {
display: flex;
justify-content: center;
}
/* 垂直居中 */
.vertical-center {
display: flex;
align-items: center;
}
等高列布局
/* Flexbox 天然支持等高 */
.columns {
display: flex;
gap: 24px;
}
.sidebar-left {
flex: 0 0 240px;
}
.main-content {
flex: 1;
}
.sidebar-right {
flex: 0 0 300px;
}
/* Flex项目默认 align-items: stretch,自然等高 */
页脚固定在底部(Sticky Footer)
/* 经典的Sticky Footer */
body {
display: flex;
flex-direction: column;
min-height: 100vh;
margin: 0;
}
main {
flex: 1; /* 主内容占据所有剩余空间 */
}
footer {
padding: 24px;
text-align: center;
}
Flex Wrap 自适应网格
/* 无需媒体查询的自适应网格 */
.auto-grid {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.auto-grid > * {
flex: 1 1 250px;
padding: 20px;
background: var(--bg-card);
border-radius: 8px;
}
/* 项目之间使用 margin 自动处理间距 */
.auto-grid > *:not(:last-child) {
margin-right: 16px;
}
Flexbox 与传统布局对比
| 需求 | 传统方式 | Flexbox 方式 |
|---|---|---|
| 水平居中 | margin: 0 auto + 固定宽度 |
justify-content: center |
| 垂直居中 | position + transform 或 table-cell | align-items: center |
| 等高列 | 需要 JavaScript 或伪元素 hack | 默认 align-items: stretch |
| 元素排序 | 调整 DOM 顺序 | order 属性 |
| 剩余空间分配 | 百分比计算 | flex-grow / flex-basis |
最佳实践
- 先设置容器:
display: flex+gap+flex-wrap - 用
gap替代 margin:更精确、更干净的间距控制 - 善用
flex: 1简写:等分空间的最快方式 - 用
flex-basis控制最小尺寸:配合min-width防止项目过小 - 避免嵌套Flex超过两层:复杂布局考虑用CSS Grid