CSS Flexbox
弹性布局全解
Flexbox 是 CSS 中最灵活的一维布局模型。它让容器能智能地 分配空间、对齐元素,无论内容尺寸是否已知都能完美适配。
核心概念
两个角色,一条轴
Flex Container
设置了 display: flex 或 inline-flex 的元素。 它定义了主轴方向和换行规则。
flex-direction主轴方向(row/column)
flex-wrap是否允许换行
justify-content主轴方向的对齐与分布
align-items交叉轴方向的对齐
gap子项之间的间距
Flex Items
Flex 容器的直接子元素。每个 item 都可以通过弹性属性 控制自身的伸缩行为和排列顺序。
flex-grow放大比例(剩余空间分配)
flex-shrink缩小比例(空间不足时)
flex-basis分配前的初始尺寸
order排列顺序(默认 0)
align-self单独覆盖交叉轴对齐
flex-direction · 主轴方向
点击切换,观察子元素排列变化
水平从左到右(默认)
.container {
display: flex;
flex-direction: row;
}justify-content · 主轴对齐
最常用的分布属性,6 种取值各有妙用
起点对齐(默认)
.container {
display: flex;
justify-content: flex-start;
}align-items · 交叉轴对齐
控制子元素在垂直(或交叉)方向的对齐
拉伸填满(默认)
.container {
display: flex;
align-items: stretch;
min-height: 200px; /* 需要足够高度才能看到效果 */
}flex-wrap · 换行控制
默认不换行 — 这也是 Flex 经常"失控"的原因
不换行(默认),可能溢出
注意:nowrap(默认值) 会让子项被压缩到极小甚至溢出容器。做卡片列表时,务必设置 flex-wrap: wrap!
flex 简写属性深度剖析
flex-grow · flex-shrink · flex-basis 的三合一
flex: <grow> <shrink> <basis>
flex-grow
存在剩余空间时,按比例分配给子项
flex-grow: 1flex-shrink
空间不足时,按比例缩小子项
flex-shrink: 0 (不缩小)flex-basis
分配前的“理想尺寸”,优先级高于 width
flex-basis: 200px常用简写值速查
flex: 0grow: 0, shrink: 1, basis: 0%固定尺寸,不伸展,可收缩flex: 1grow: 1, shrink: 1, basis: 0%等分剩余空间(最常用!)flex: autogrow: 1, shrink: 1, basis: auto根据内容自适应,可伸缩flex: nonegrow: 0, shrink: 0, basis: auto完全固定,不伸不缩flex: 200pxgrow: 1, shrink: 1, basis: 200px基础 200px,可弹性伸缩交互实验:flex-grow
调整第二个元素的 grow 值,观察空间分配变化
当 grow: 0 时保持基础宽度;grow 越大,占的剩余空间越多
实战模式库
8 个最经典的 Flexbox 布局模式
完美居中
最经典的一行居中代码
display: flex;
justify-content: center;
align-items: center;导航栏
Logo 左 + 菜单右的经典布局
display: flex;
justify-content: space-between;
align-items: center;等分布局
flex: 1 让所有子项等宽
display: flex;
> * { flex: 1; }卡片底部对齐
flex 列 + margin-top: auto
display: flex;
flex-direction: column;
> .cta { margin-top: auto; }输入框组
输入框 flex: 1 + 固定按钮
display: flex;
input { flex: 1; }
button { flex-shrink: 0; }Sticky Footer
最小全高页面,底部永远贴底
body {
display: flex;
flex-direction: column;
min-height: 100vh;
}
footer { margin-top: auto; }两端对齐行
标题左 + 操作右
display: flex;
justify-content: space-between;
align-items: center;媒体对象
图片固定 + 文字弹性填充
display: flex;
gap: 16px;
img { flex-shrink: 0; }
text { flex: 1; }gap · 告别 margin hack
Flexbox 现已全面支持 gap 属性
/* 旧方案:需要 :not(:last-child) */
.item:not(:last-child) {
margin-right: 16px;
}
/* 问题:最后一个元素也有 margin *//* 现代方案:一行搞定 */
.container {
display: flex;
gap: 16px;
/* 或 gap: row-gap column-gap */
}margin-right: 16px (旧方案)
← 注意最后的多余间距
gap: 16px (现代方案)
← 干净利落,无多余间距
Flexbox vs Grid 选择指南
不是"谁更好",而是"什么时候用谁"
布局是几维的?
1D: Flexbox → 单行/单列
2D: Grid → 行 + 列同时控制
内容还是布局优先?
1D: Flexbox → 内容驱动,自适应
2D: Grid → 布局驱动,先画骨架
元素间需要对齐关系吗?
1D: Flexbox → 各自为政
2D: Grid → 行列对齐
💡 Flexbox 是你的瑞士军刀,Grid 是你的建筑蓝图
日常 90% 的布局需求,Flexbox 都能优雅解决。
完整属性速查表
Flexbox 全部属性一览
| 属性 | 作用对象 | 说明 |
|---|---|---|
display: flex | 容器 | 声明一个 Flex 容器 |
flex-direction | 容器 | 主轴方向(row/column/row-reverse/column-reverse) |
flex-wrap | 容器 | 换行控制(nowrap/wrap/wrap-reverse) |
flex-flow | 容器 | direction + wrap 的简写 |
justify-content | 容器 | 主轴对齐与分布(6 种取值) |
align-items | 容器 | 交叉轴对齐(stretch/flex-start/center/flex-end/baseline) |
align-content | 容器 | 多行交叉轴对齐(需 wrap) |
gap / row-gap / column-gap | 容器 | 子项之间的间距 |
flex-grow | 子项 | 剩余空间放大比例(默认 0) |
flex-shrink | 子项 | 空间不足时缩小比例(默认 1) |
flex-basis | 子项 | 分配前的初始尺寸(默认 auto) |
flex | 子项 | grow + shrink + basis 的简写 |
order | 子项 | 排列顺序(默认 0,越小越前) |
align-self | 子项 | 单独覆盖交叉轴对齐 |
常见坑点 & 最佳实践
这些经验能帮你避免 80% 的 Flex 布局问题
flex-shrink 默认为 1
子项默认会被压缩。如果不想缩小,设置 flex-shrink: 0 或 flex: none。
min-width 的隐形陷阱
Flex 子项默认 min-width: auto(最小为内容宽度),可能导致不换行。设置 min-width: 0 可修复。
margin: auto 的超能力
在 Flex 子项上设置 margin-left: auto 可以让它“吸”到另一端,比 justify-content 更灵活。
gap 代替 margin
现代浏览器已全面支持 Flex 的 gap 属性,告别 margin hack,代码更简洁。
flex-basis 优先于 width
当同时设置 width 和 flex-basis 时,flex-basis 优先。建议统一使用 flex 简写。
百分比 vs fr vs auto
flex: 1 等于 flex: 1 1 0%,而 flex: auto 等于 flex: 1 1 auto。两者行为不同!