Flex 布局全面指南
很多同学第一次学 Flex 时,会觉得它“看起来很简单,但一写就容易乱”:
- 为什么有时候是横着排,有时候又变成竖着排?
- 为什么
justify-content有时能动,有时看起来像没生效? - 为什么子项明明写了省略号,却还是把容器撑爆了?
- 为什么
flex: 1到底不是“平均分一切”这么简单?
这很正常,因为 Flex 不是一个属性,而是一整套一维布局规则。
它解决的问题是:在一条轴线上,如何排序、换行、伸缩、对齐和分配剩余空间。
本文会把 Flex 布局中的核心概念、容器属性、子项属性、尺寸分配规则、常见坑点和高频面试题一次讲清楚,尽量做到:不只会背语法,还知道浏览器为什么这样排。
一、先建立 4 个最重要的概念
学 Flex 之前,先别急着背属性,先把下面这 4 个概念记住。
1.1 Flex 是一维布局
Flex 最擅长处理的是一条线上的布局。
- 你可以让元素沿着一行排列
- 也可以让元素沿着一列排列
- 重点不是“画网格”,而是“在主轴上分配空间”
所以它特别适合:
- 导航栏
- 按钮组
- 标签流
- 卡片内部排版
- 左右两栏
- 头部 / 内容 / 底部的纵向结构
如果你要处理的是“同时控制行和列”的二维结构,比如后台面板、复杂卡片墙、页面骨架,通常 Grid 更合适。
1.2 什么是 Flex 容器和 Flex 子项
当一个元素设置了:
.container {
display: flex;
}
或者:
.container {
display: inline-flex;
}
那么:
- 这个父元素叫 Flex 容器(flex container)
- 它的直接子元素叫 Flex 子项(flex items)
注意两个关键词:
- 直接子元素 才是 Flex item
- 孙子元素不会自动变成 Flex item,除非你再给它的父元素开一个 Flex 容器
1.3 主轴和交叉轴
Flex 里最重要的不是“水平 / 垂直”,而是:
- 主轴(main axis):元素主要排列和分配空间的那条轴
- 交叉轴(cross axis):与主轴垂直的那条轴
主轴方向由 flex-direction 决定:
flex-direction | 主轴方向 | 交叉轴方向 |
|---|---|---|
row | 从左到右(默认) | 从上到下 |
row-reverse | 从右到左 | 从上到下 |
column | 从上到下 | 从左到右 |
column-reverse | 从下到上 | 从左到右 |
所以你以后看到这些属性时,要自动联想到它们分别管哪条轴:
justify-content:管主轴align-items:管交叉轴align-content:管多行时的交叉轴整体分布
先别死背“justify-content 是水平,align-items 是垂直”。
更稳的记法是:
justify-content永远管主轴align-items永远管交叉轴
因为当你把 flex-direction 改成 column 时,这两个属性“看起来的方向”会跟着变。
1.4 起点、终点、反向
Flex 中还经常会碰到这些词:
main-start:主轴起点main-end:主轴终点cross-start:交叉轴起点cross-end:交叉轴终点
当你写 row-reverse 或 column-reverse 时,改变的是视觉排列方向,不是 DOM 结构本身。
这件事很重要,因为它会影响:
- 屏幕阅读器阅读顺序
- 键盘 Tab 焦点顺序
- 可访问性理解
也就是说:反向只改“看起来怎么排”,不会改“文档本身怎么读”。
二、怎么开启 Flex 布局
2.1 display: flex 和 display: inline-flex
.toolbar {
display: flex;
}
.tag-list {
display: inline-flex;
}
两者区别是:
display: flex:容器在外部表现为块级盒子display: inline-flex:容器在外部表现为行内级盒子
但它们的内部子项排版规则,都是 Flex。
2.2 开启 Flex 后,会发生什么
容器开启 Flex 后,浏览器会创建 Flex Formatting Context(FFC,弹性格式化上下文)。
你可以简单理解为:
- 子项不再按普通文档流那套“块挨着块、行内挨着行内”的方式排
- 而是进入 Flex 的主轴 / 交叉轴分配系统
一些常见现象也会随之出现:
- 子项默认会在主轴上排成一条线
- 子项默认允许收缩(
flex-shrink: 1) float、clear、vertical-align对 Flex item 往往不会产生你在普通流里期待的效果
三、Flex 容器的所有核心属性
先记一句话:容器属性负责定方向、定换行、定对齐、定间距。
3.1 flex-direction:决定主轴方向
.container {
display: flex;
flex-direction: row;
}
可选值有 4 个:
row:从左到右,默认值row-reverse:从右到左column:从上到下column-reverse:从下到上
.row {
flex-direction: row;
}
.column {
flex-direction: column;
}
渲染结果:
row 并不等于“永远水平”更准确地说,row 是沿着 inline 轴 排列。在大多数中文网页的默认书写模式下,它看起来就是从左到右。
初学阶段先把它理解成“默认横向排布”就够用了。
3.2 flex-wrap:子项是否允许换行
默认情况下,Flex 子项会尽量排在同一行:
.container {
display: flex;
flex-wrap: nowrap;
}
常见值:
nowrap:不换行,默认值wrap:换行wrap-reverse:换行,但交叉轴方向反过来
.card-list {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
渲染结果:
什么时候你会明显感受到 wrap 很重要?
- 标签流 / 分类标签
- 卡片列表
- 工具按钮区
- 响应式导航菜单
如果你不写 wrap,子项通常会优先收缩,而不是主动换行。
3.3 flex-flow:flex-direction + flex-wrap 的简写
.container {
display: flex;
flex-flow: row wrap;
}
等价于:
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
常见写法:
flex-flow: row nowrap;flex-flow: row wrap;flex-flow: column nowrap;
如果你经常同时写方向和换行,这个简写很顺手。
3.4 justify-content:主轴上的对齐与剩余空间分配
这个属性控制的是:子项在主轴上怎么摆。
.container {
display: flex;
justify-content: center;
}
最常用的值有:
| 值 | 含义 |
|---|---|
flex-start | 靠主轴起点 |
flex-end | 靠主轴终点 |
center | 居中 |
space-between | 两端贴边,中间等距 |
space-around | 每个项目两侧都有空间 |
space-evenly | 所有间距完全相等 |
start / end | 逻辑方向上的起点 / 终点,现代写法 |
.nav {
display: flex;
justify-content: space-between;
}
渲染结果:
justify-content 却没感觉?因为 justify-content 分配的是 剩余空间。
如果你的子项已经通过 flex-grow 把主轴空间吃满了,那它就没多少“剩余空间”可分了,看起来就像没生效。
当 flex-direction: column 时,justify-content 控制的就会变成竖向分布。
3.5 align-items:交叉轴上的默认对齐方式
这个属性控制的是:所有子项在交叉轴上怎么对齐。
.container {
display: flex;
align-items: center;
}
常见值:
| 值 | 含义 |
|---|---|
stretch | 拉伸填满交叉轴,默认值 |
flex-start | 靠交叉轴起点 |
flex-end | 靠交叉轴终点 |
center | 交叉轴居中 |
baseline | 按文字基线对齐 |
补充一点:现代 Box Alignment 规范里还支持 start、end、self-start、self-end、safe center 等写法,但日常 Flex 开发里最常用的还是上面这几个。
.toolbar {
display: flex;
align-items: center;
}
什么时候 stretch 明显有感觉?
当容器在交叉轴上有明确尺寸时,且子项该方向没有固定大小,就会看到被拉伸。
例如:
.row {
display: flex;
height: 120px;
align-items: stretch;
}
如果你想让按钮、图标和文字在导航栏垂直居中,align-items: center 是你最常写的一句。
3.6 align-content:多行 Flex 在交叉轴上的整体分布
这是 Flex 里最容易被误用的属性之一。
它控制的不是“单个子项”,而是:多条 Flex 行(line)在交叉轴上如何分布。
.container {
display: flex;
flex-wrap: wrap;
align-content: space-between;
}
常见值和 justify-content 很像:
flex-startflex-endcenterspace-betweenspace-aroundspace-evenlystretch
align-content 不生效,十有八九是这两个原因- 你的容器根本没有换成多行(没有
flex-wrap: wrap) - 容器在交叉轴上没有多余空间可分配
所以它几乎总是和这两个条件一起出现:
flex-wrap: wrap- 容器有足够的交叉轴尺寸
例如:
.gallery {
display: flex;
flex-wrap: wrap;
align-content: space-between;
height: 320px;
gap: 12px;
}
3.7 gap、row-gap、column-gap:项目间距
现代 Flex 布局非常推荐直接用 gap 控制项目之间的间距。
.actions {
display: flex;
gap: 12px;
}
或者分开写:
.actions {
display: flex;
row-gap: 12px;
column-gap: 20px;
}
它的优点是:
- 只控制项目之间的距离
- 不会给首尾平白多出外边距
- 换行后依然清晰
- 可读性通常比给每个子项写
margin更好
渲染结果:
3.8 补充:哪些“对齐属性”对 Flex 不起作用
很多同学会下意识去写:
.item {
justify-self: end;
}
但在 Flex 里,justify-self 基本不生效。
同样地:
justify-items对 Flex 容器通常也没有实际作用place-items在 Flex 中也不如 Grid 里常用
在 Flex 中如果你想把某个项目“往主轴另一边推”,更常见的做法是:
.login-btn {
margin-left: auto;
}
这个技巧后面还会讲到。
四、Flex 子项的所有核心属性
先记一句话:子项属性负责控制自己排第几、占多少、缩不缩、单独怎么对齐。
4.1 order:控制视觉顺序
.item-a {
order: 2;
}
.item-b {
order: 1;
}
规则是:
- 默认值是
0 - 数字越小,越靠前
- 可以写负数
例如:
.sidebar {
order: 2;
}
.main {
order: 1;
}
这样视觉上 main 会排到前面。
order 只改视觉顺序,不改 DOM 顺序这意味着:
- 屏幕阅读器读取顺序通常还是原来的 DOM 顺序
- 键盘焦点顺序通常也还是原来的 DOM 顺序
所以 order 很适合做小范围视觉调整,不适合拿来“重构语义结构”。
4.2 flex-grow:有剩余空间时怎么分
.item {
flex-grow: 1;
}
它表示:当主轴上有剩余空间时,这个子项愿意按什么比例去分。
比如:
.a {
flex-grow: 1;
}
.b {
flex-grow: 2;
}
.c {
flex-grow: 1;
}
那么剩余空间会按 1 : 2 : 1 分。
渲染结果:
注意:flex-grow 分配的是剩余空间,不是直接决定元素最终宽度。
4.3 flex-shrink:空间不够时怎么缩
.item {
flex-shrink: 1;
}
它表示:当主轴空间不够时,这个子项允许按什么比例收缩。
默认值是:
flex-shrink: 1;
也就是说,Flex item 默认是愿意缩的。
如果你不希望某个项目被压缩,可以写:
.avatar {
flex-shrink: 0;
}
常见场景:
- 头像不想被挤变形
- 固定宽按钮不想被压瘪
- 侧边栏不想在小屏下被过度压缩
4.4 flex-basis:分配空间前的“基础尺寸”
.item {
flex-basis: 200px;
}
你可以把它理解成:浏览器在计算伸缩之前,先拿这个值当作项目的起始尺寸。
常见写法:
.item {
flex-basis: auto;
}
.card {
flex-basis: 240px;
}
.panel {
flex-basis: 30%;
}
常见值:
auto:参考项目本身尺寸或内容- 长度值:如
200px - 百分比:如
30% content:以内容尺寸作为基础(较少单独手写)
flex-basis 和 width 谁优先?如果你在主轴方向上同时写了 width 和 flex-basis,且 flex-basis 不是 auto,通常以 flex-basis 为准。
例如在 row 布局里:
.item {
width: 300px;
flex-basis: 200px;
}
浏览器更会把它当成“基础宽度 200px 的项目”来参与计算。
4.5 flex:grow shrink basis 的简写
这是 Flex 最常用、也最容易背错的属性。
.item {
flex: 1;
}
它其实是下面三个属性的简写:
flex-grow
flex-shrink
flex-basis
最常见的几种写法
| 写法 | 等价形式 | 含义 |
|---|---|---|
flex: initial | 0 1 auto | 默认行为:不主动扩张,可收缩,基础尺寸看内容 / 宽高 |
flex: auto | 1 1 auto | 可扩张、可收缩,基础尺寸看内容 |
flex: none | 0 0 auto | 不扩张、不收缩 |
flex: 1 | 1 1 0% | 忽略内容基础尺寸,按比例分剩余空间 |
flex: 0 0 240px | 0 0 240px | 固定基准 240px,不伸不缩 |
为什么 flex: 1 很常见?
因为它通常非常适合“几列平均分剩余空间”的场景:
.item {
flex: 1;
}
但请你一定记住:
flex: 1 不是“宽度自动相等”的魔法,它本质是 1 1 0%。
这里的 0% 很关键:
- 它告诉浏览器:先把每个项目的基础尺寸当成 0
- 再按
grow比例去分剩余空间
所以它比 flex: auto 更“平均”,因为它更少考虑原始内容大小。
4.6 align-self:覆盖单个子项的交叉轴对齐
容器写了:
.container {
display: flex;
align-items: center;
}
如果某一个子项你想单独处理,可以写:
.special {
align-self: flex-end;
}
常见值和 align-items 很像:
autostretchflex-startflex-endcenterbaseline
例如:
.badge {
align-self: flex-start;
}
这在下面这些场景很常见:
- 某个按钮需要贴顶部
- 某个徽标要与其他内容错位强调
- 某个卡片项要打破统一垂直对齐
4.7 margin: auto:Flex 里非常好用的“推开”技巧
在 Flex 中,自动外边距特别实用。
例如:
.nav {
display: flex;
align-items: center;
}
.login-btn {
margin-left: auto;
}
效果就是:把 login-btn 推到主轴另一侧。
这招特别适合:
- 导航栏右侧按钮
- 工具栏“最后一个操作项”顶到最右
- 卡片底部按钮推到底部(配合列布局)
竖向布局里也一样:
.card {
display: flex;
flex-direction: column;
}
.card__action {
margin-top: auto;
}
这样按钮就会被推到卡片底部。
五、真正理解 Flex:浏览器到底怎么分配空间
如果你只会背属性,很快就会碰到“怎么跟我想的不一样”。
真正稳定的做法,是理解 Flex 的大致分配过程。
你可以把它先粗略理解成下面 5 步:
5.1 第一步:确定主轴方向
浏览器先看 flex-direction:
row/row-reverse:主轴主要是横向column/column-reverse:主轴主要是纵向
5.2 第二步:看每个项目的基础尺寸
这个基础尺寸通常与这些因素有关:
flex-basiswidth/height- 内容本身大小
5.3 第三步:算出主轴上还有多少剩余空间
如果有正的剩余空间,就进入 flex-grow 分配。
如果空间不够,就进入 flex-shrink 收缩。
5.4 第四步:按比例扩张或收缩
- 有多余空间:按
flex-grow比例分 - 空间不足:按
flex-shrink规则缩
5.5 第五步:再受最小 / 最大尺寸限制
即使你写了伸缩,浏览器最后还会看这些限制:
min-widthmax-widthmin-heightmax-height
这也是很多“为什么它就是不缩”的根源。
5.6 为什么 Flex 子项经常需要 min-width: 0
这是前端面试和日常开发里都特别高频的坑。
看这个常见结构:
.row {
display: flex;
gap: 12px;
}
.title {
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
很多同学会发现:明明写了省略号,标题还是把容器撑爆。
这时通常要补一句:
.title {
flex: 1;
min-width: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
为什么?
因为 Flex item 默认的最小尺寸往往不是你以为的 0,而是更偏向“内容别被压碎”的策略。这样它就可能宁可撑开,也不愿继续缩。
min-width: 0 的意思就是明确告诉浏览器:
这个项目可以真的缩小。
只要你在横向 Flex 布局里遇到:
- 长标题
- 长链接
- 文件名
- 表格单元格内容
并且它死活不肯省略,优先想到:min-width: 0。
5.7 为什么列布局里经常需要 min-height: 0
在纵向 Flex 布局中也有对应问题:
.page {
display: flex;
flex-direction: column;
height: 100vh;
}
.main {
flex: 1;
min-height: 0;
overflow: auto;
}
这段写法很常见于:
- 顶部固定 + 中间滚动内容
- 后台管理页面
- 聊天窗口
如果不写 min-height: 0,中间内容区有时会无法按预期收缩和滚动。
六、Flex 布局的常见实战写法
这一节不讲新语法,只讲工作里最常见的组合。
6.1 导航栏:左边品牌,右边按钮
<header class="nav">
<div class="logo">Werry</div>
<nav class="menu">
<a>首页</a>
<a>文档</a>
<a>博客</a>
</nav>
<button class="login-btn">登录</button>
</header>
.nav {
display: flex;
align-items: center;
gap: 16px;
}
.menu {
display: flex;
gap: 12px;
}
.login-btn {
margin-left: auto;
}
核心思想:不要硬算右边距,直接用 margin-left: auto 把按钮推到最右。
6.2 左侧固定,右侧自适应
.layout {
display: flex;
gap: 20px;
}
.sidebar {
flex: 0 0 240px;
}
.content {
flex: 1;
min-width: 0;
}
这套写法非常经典:
- 左边固定 240px
- 右边吃掉剩余空间
- 右边允许真的缩小
6.3 卡片列表自动换行
.card-list {
display: flex;
flex-wrap: wrap;
gap: 16px;
}
.card {
flex: 1 1 260px;
}
这表示:
- 基础尺寸先按 260px 计算
- 放得下就一行多列
- 放不下就换行
- 同一行里还可以继续伸缩
这个模式特别适合响应式卡片墙。
6.4 底部操作按钮永远贴卡片底部
.card {
display: flex;
flex-direction: column;
min-height: 280px;
}
.card__content {
margin-bottom: 16px;
}
.card__action {
margin-top: auto;
}
核心思想:在列布局里,margin-top: auto 会把按钮往底部推。
6.5 粘性页脚结构
body {
min-height: 100vh;
display: flex;
flex-direction: column;
}
main {
flex: 1;
}
这样即使内容不多,页脚也能自然待在页面底部。
七、Flex 和 Grid 到底怎么选
这是非常高频的问题。
| 对比项 | Flex | Grid |
|---|---|---|
| 核心定位 | 一维布局 | 二维布局 |
| 思维方式 | 沿主轴分配空间 | 先定义行列,再摆放元素 |
| 更擅长 | 组件内部排版、线性排列 | 页面骨架、复杂区域布局 |
| 常见场景 | 导航、按钮组、工具栏、卡片内部 | 仪表盘、瀑布式区域、后台框架 |
一个很好用的经验法则是:
- 排一条线,用 Flex
- 画一个面,用 Grid
在真实项目里,两者经常一起出现:
- 页面外层骨架用
Grid - 卡片内部按钮区、标题区、头像区用
Flex
八、Flex 最常见的误区和坑点
8.1 把 justify-content 和 align-items 背成固定水平 / 垂直
这在 row 布局里看着像对,但一旦切成 column,你就容易乱。
正确记法还是那句:
justify-content管主轴align-items管交叉轴
8.2 align-content 对单行布局没用
如果没有换行,只有一条 Flex line,那么 align-content 基本没有发挥空间。
8.3 order 和 reverse 不会改变语义顺序
它们只改变视觉顺序,不改变 DOM 顺序和通常的焦点顺序。
8.4 flex: 1 不等于“完全无脑平均”
它更准确地等价于:
flex: 1 1 0%;
也就是说,它是从“基础尺寸 0”出发去分空间,不是从内容真实宽度出发。
8.5 长内容撑爆布局,优先想到 min-width: 0
这是实战里极其常见的坑。
8.6 列布局里的滚动区域,优先想到 min-height: 0
尤其是后台、聊天区、页面主体滚动布局。
8.7 gap 更适合控制项目间距,margin 更适合控制组件外部关系
这不是绝对规则,但通常这样更清晰:
- 同一容器内部的项目间距,用
gap - 组件和组件之间的外部距离,用
margin
九、Flex 属性速查表
9.1 容器属性速查
| 属性 | 作用 | 常见值 | 说明 |
|---|---|---|---|
display | 开启 Flex 布局 | flex / inline-flex | 定义 Flex 容器 |
flex-direction | 定义主轴方向 | row / row-reverse / column / column-reverse | 决定元素主要怎么排 |
flex-wrap | 是否换行 | nowrap / wrap / wrap-reverse | 控制单行还是多行 |
flex-flow | 简写 | 如 row wrap | direction + wrap |
justify-content | 主轴对齐 | flex-start / center / space-between 等 | 分配主轴剩余空间 |
align-items | 子项在交叉轴上的默认对齐 | stretch / center / baseline 等 | 管所有子项 |
align-content | 多行在交叉轴上的整体分布 | stretch / space-between 等 | 只有多行时有意义 |
gap | 行列间距简写 | 12px / 1rem | 推荐优先使用 |
row-gap | 行间距 | 长度值 | 多行时更明显 |
column-gap | 列间距 | 长度值 | 横向间距 |
place-content | align-content + justify-content 简写 | 如 center space-between | Flex 中较少单独使用 |
9.2 子项属性速查
| 属性 | 作用 | 常见值 | 说明 |
|---|---|---|---|
order | 控制视觉顺序 | 数字 | 数字越小越靠前 |
flex-grow | 有剩余空间时如何扩张 | 0 / 1 / 2... | 按比例分正空间 |
flex-shrink | 空间不足时如何收缩 | 1 / 0 | 默认可收缩 |
flex-basis | 基础尺寸 | auto / 200px / 30% | 先按它参与计算 |
flex | 简写 | 1 / auto / none / 0 0 240px | 最常用 |
align-self | 单个项目交叉轴对齐 | auto / center / flex-end 等 | 覆盖容器的 align-items |
margin: auto | 利用自动外边距推开项目 | 如 margin-left: auto | Flex 里很实用 |
9.3 两个必须记住的“不生效”点
justify-self对 Flex item 基本不生效justify-items对 Flex 容器通常也没有实际意义
十、高频面试问答
Q1:Flex 和 Grid 的本质区别是什么?
参考答案:
Flex 是一维布局,主要解决一条轴线上的排序、对齐和空间分配;Grid 是二维布局,适合同时控制行和列。组件内部排版通常优先用 Flex,页面骨架或复杂区域布局更适合 Grid。
Q2:flex: 1 到底等于什么?
参考答案:
在常见语义下,flex: 1 等价于 flex: 1 1 0%。表示该项目可以增长、可以收缩,并且基础尺寸从 0% 开始参与剩余空间分配。
Q3:flex: auto 和 flex: 1 有什么区别?
参考答案:
flex: auto 等价于 1 1 auto,会更尊重项目自身内容或宽高;flex: 1 等价于 1 1 0%,更像从统一起跑线出发分配空间,因此通常更“平均”。
Q4:justify-content 和 align-items 的区别是什么?
参考答案:
justify-content 控制主轴上的分布,align-items 控制交叉轴上的对齐。不要死记成“水平 / 垂直”,因为当 flex-direction 变成 column 时,主轴和交叉轴会跟着变化。
Q5:为什么 align-content 经常不生效?
参考答案:
因为 align-content 只有在多行 Flex 布局中才有明显意义。若没有 flex-wrap: wrap,或容器交叉轴上没有多余空间,它看起来就像没生效。
Q6:flex-basis 和 width 的区别是什么?
参考答案:
flex-basis 是 Flex 计算时的基础尺寸,优先级通常高于主轴方向上的 width / height。在 row 布局里,如果 flex-basis 不是 auto,它往往比 width 更先参与空间分配。
Q7:为什么 Flex 布局里经常要写 min-width: 0?
参考答案:
因为 Flex item 默认最小尺寸策略可能阻止它继续缩小,导致长文本把布局撑爆。写上 min-width: 0 是明确告诉浏览器:这个项目允许继续缩小,从而让省略号、滚动或弹性分配正常工作。
Q8:order 会不会改变页面真实顺序?
参考答案:
不会。order 只改变视觉顺序,不改变 DOM 顺序,也通常不改变屏幕阅读器和键盘焦点的逻辑顺序,所以不能把它当作语义重排工具。
Q9:为什么在 Flex 里 justify-self 不生效?
参考答案:
因为 Flex 的主轴空间分配是围绕整条 Flex line 设计的,单个项目在主轴上的“自我对齐”不是通过 justify-self 完成的。常见替代方式是使用自动外边距,例如 margin-left: auto。
Q10:什么时候该用 margin-left: auto?
参考答案:
当你需要把某个项目推到主轴另一端时,这个技巧非常高效。典型场景是导航栏右侧按钮、工具栏尾部操作项、卡片底部按钮对齐。
Q11:flex-shrink: 0 常见在什么场景?
参考答案:
常用于头像、图标、固定宽按钮、侧边栏等不希望在空间不足时被压缩变形的元素。
Q12:列布局中为什么常配合 min-height: 0?
参考答案:
因为纵向 Flex 布局里的中间区域如果既要弹性占满剩余高度,又要内部滚动,默认最小高度策略可能阻止它收缩。min-height: 0 能让它真正缩下来,从而配合 overflow: auto 正常工作。
十一、总结
如果你学完整篇文章,只记住下面这 8 句话,也已经很够用了:
- Flex 是一维布局,核心是主轴和交叉轴。
- 容器属性负责定方向、换行、对齐和间距。
- 子项属性负责定顺序、伸缩比例、基础尺寸和单独对齐。
justify-content管主轴,align-items管交叉轴。align-content只在多行布局里更有意义。flex: 1本质上是1 1 0%。- 长内容撑爆 Flex 时,优先想到
min-width: 0。 - 排一条线用 Flex,画一个面用 Grid。
如果你愿意继续深入,下一步很适合配套学习:
Grid 布局BFC / IFC / GFC定位(position)CSS 单位继承、层叠与优先级
把这些知识串起来后,你对 CSS 布局的理解会完整很多。