跳到主要内容

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)

注意两个关键词:

  1. 直接子元素 才是 Flex item
  2. 孙子元素不会自动变成 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-reversecolumn-reverse 时,改变的是视觉排列方向,不是 DOM 结构本身。

这件事很重要,因为它会影响:

  • 屏幕阅读器阅读顺序
  • 键盘 Tab 焦点顺序
  • 可访问性理解

也就是说:反向只改“看起来怎么排”,不会改“文档本身怎么读”。


二、怎么开启 Flex 布局

2.1 display: flexdisplay: 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
  • floatclearvertical-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
A
B
C
row-reverse
A
B
C
column
A
B
C
column-reverse
A
B
C
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;
}

渲染结果:

nowrap
1
2
3
4
wrap
1
2
3
4
wrap-reverse
1
2
3
4

什么时候你会明显感受到 wrap 很重要?

  • 标签流 / 分类标签
  • 卡片列表
  • 工具按钮区
  • 响应式导航菜单

如果你不写 wrap,子项通常会优先收缩,而不是主动换行。


3.3 flex-flowflex-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: space-between
Logo
菜单
登录
为什么我写了 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 规范里还支持 startendself-startself-endsafe 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-start
  • flex-end
  • center
  • space-between
  • space-around
  • space-evenly
  • stretch
align-content 不生效,十有八九是这两个原因
  1. 你的容器根本没有换成多行(没有 flex-wrap: wrap
  2. 容器在交叉轴上没有多余空间可分配

所以它几乎总是和这两个条件一起出现:

  • flex-wrap: wrap
  • 容器有足够的交叉轴尺寸

例如:

.gallery {
display: flex;
flex-wrap: wrap;
align-content: space-between;
height: 320px;
gap: 12px;
}

3.7 gaprow-gapcolumn-gap:项目间距

现代 Flex 布局非常推荐直接用 gap 控制项目之间的间距。

.actions {
display: flex;
gap: 12px;
}

或者分开写:

.actions {
display: flex;
row-gap: 12px;
column-gap: 20px;
}

它的优点是:

  • 只控制项目之间的距离
  • 不会给首尾平白多出外边距
  • 换行后依然清晰
  • 可读性通常比给每个子项写 margin 更好

渲染结果:

gap: 12px
按钮 A
按钮 B
按钮 C
按钮 D

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: 1 / 2 / 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-basiswidth 谁优先?

如果你在主轴方向上同时写了 widthflex-basis,且 flex-basis 不是 auto,通常以 flex-basis 为准。

例如在 row 布局里:

.item {
width: 300px;
flex-basis: 200px;
}

浏览器更会把它当成“基础宽度 200px 的项目”来参与计算。


4.5 flexgrow shrink basis 的简写

这是 Flex 最常用、也最容易背错的属性。

.item {
flex: 1;
}

它其实是下面三个属性的简写:

flex-grow
flex-shrink
flex-basis

最常见的几种写法

写法等价形式含义
flex: initial0 1 auto默认行为:不主动扩张,可收缩,基础尺寸看内容 / 宽高
flex: auto1 1 auto可扩张、可收缩,基础尺寸看内容
flex: none0 0 auto不扩张、不收缩
flex: 11 1 0%忽略内容基础尺寸,按比例分剩余空间
flex: 0 0 240px0 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 很像:

  • auto
  • stretch
  • flex-start
  • flex-end
  • center
  • baseline

例如:

.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-basis
  • width / height
  • 内容本身大小

5.3 第三步:算出主轴上还有多少剩余空间

如果有正的剩余空间,就进入 flex-grow 分配。

如果空间不够,就进入 flex-shrink 收缩。

5.4 第四步:按比例扩张或收缩

  • 有多余空间:按 flex-grow 比例分
  • 空间不足:按 flex-shrink 规则缩

5.5 第五步:再受最小 / 最大尺寸限制

即使你写了伸缩,浏览器最后还会看这些限制:

  • min-width
  • max-width
  • min-height
  • max-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 到底怎么选

这是非常高频的问题。

对比项FlexGrid
核心定位一维布局二维布局
思维方式沿主轴分配空间先定义行列,再摆放元素
更擅长组件内部排版、线性排列页面骨架、复杂区域布局
常见场景导航、按钮组、工具栏、卡片内部仪表盘、瀑布式区域、后台框架

一个很好用的经验法则是:

  • 排一条线,用 Flex
  • 画一个面,用 Grid

在真实项目里,两者经常一起出现:

  • 页面外层骨架用 Grid
  • 卡片内部按钮区、标题区、头像区用 Flex

八、Flex 最常见的误区和坑点

8.1 把 justify-contentalign-items 背成固定水平 / 垂直

这在 row 布局里看着像对,但一旦切成 column,你就容易乱。

正确记法还是那句:

  • justify-content 管主轴
  • align-items 管交叉轴

8.2 align-content 对单行布局没用

如果没有换行,只有一条 Flex line,那么 align-content 基本没有发挥空间。

8.3 orderreverse 不会改变语义顺序

它们只改变视觉顺序,不改变 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 wrapdirection + 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-contentalign-content + justify-content 简写center space-betweenFlex 中较少单独使用

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: autoFlex 里很实用

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: autoflex: 1 有什么区别?

参考答案:

flex: auto 等价于 1 1 auto,会更尊重项目自身内容或宽高;flex: 1 等价于 1 1 0%,更像从统一起跑线出发分配空间,因此通常更“平均”。

Q4:justify-contentalign-items 的区别是什么?

参考答案:

justify-content 控制主轴上的分布,align-items 控制交叉轴上的对齐。不要死记成“水平 / 垂直”,因为当 flex-direction 变成 column 时,主轴和交叉轴会跟着变化。

Q5:为什么 align-content 经常不生效?

参考答案:

因为 align-content 只有在多行 Flex 布局中才有明显意义。若没有 flex-wrap: wrap,或容器交叉轴上没有多余空间,它看起来就像没生效。

Q6:flex-basiswidth 的区别是什么?

参考答案:

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 句话,也已经很够用了:

  1. Flex 是一维布局,核心是主轴和交叉轴。
  2. 容器属性负责定方向、换行、对齐和间距。
  3. 子项属性负责定顺序、伸缩比例、基础尺寸和单独对齐。
  4. justify-content 管主轴,align-items 管交叉轴。
  5. align-content 只在多行布局里更有意义。
  6. flex: 1 本质上是 1 1 0%
  7. 长内容撑爆 Flex 时,优先想到 min-width: 0
  8. 排一条线用 Flex,画一个面用 Grid。

如果你愿意继续深入,下一步很适合配套学习:

  • Grid 布局
  • BFC / IFC / GFC
  • 定位(position)
  • CSS 单位
  • 继承、层叠与优先级

把这些知识串起来后,你对 CSS 布局的理解会完整很多。