Flex弹性布局
前言
关于flex布局,网上有很多教程,但是这里记录一下我自己学习中容易踩坑的点:flex布局里面的主轴和交叉轴,不能简单的理解为横竖轴,如果映入这个想法,很容易弄混,增加学习的难度,主轴就是默认的排列方向,默认是横向,当然可以改为竖向,这时候主轴就是竖的,初学很容易就卡这一步了,什么乱七八糟横竖主轴交叉轴,所以只要记住主轴交叉轴就可以;
关于flex概念,只要设置一个display:flex,那这个元素就自动成为flex容器,里面的子元素就是flex项目,flex主要分为容器属性和项目属性,以上这句话包括了很多重点,只要明白flex容器,flex项目,以及它们各自属性基本就能使用flex布局了
Flex基础知识
什么是flex布局:是 CSS 提供的一种一维布局方式,主要用于控制元素在水平或垂直方向上的排列、对齐、间距和伸缩。任何一个HTML元素都可以指定为flex布局;
什么是flex容器:设置了 display: flex 或 display: inline-flex 的元素就是flex容器
什么是flex项目:Flex 容器中的直接子元素。需要注意:只有 Flex 容器的直接子元素会成为 Flex 项目。Flex 项目的内部元素不会自动成为该容器的 Flex 项目。Flex 容器本身也可以同时是另一个 Flex 容器的 Flex 项目。
什么是主轴,什么是交叉轴:主轴(Main Axis):Flex 项目主要排列的方向,由 flex-direction 决定。交叉轴(Cross Axis):与主轴垂直的方向。主轴不一定是水平方向,交叉轴也不一定是垂直方向。
Flex容器的属性
修改主轴方向
flex-direction 用于设置 Flex 容器的主轴方向,决定 Flex 项目沿哪个方向排列。
基本语法:
.container { display: flex; flex-direction: row;}| 属性值 | 说明 |
|---|---|
row | 默认值,主轴为水平方向,通常从左向右排列 |
row-reverse | 主轴为水平方向,通常从右向左排列 |
column | 主轴为垂直方向,通常从上向下排列 |
column-reverse | 主轴为垂直方向,通常从下向上排列 |
是否换行
flex-wrap 用于设置当 Flex 项目在主轴方向上排列空间不足时,是否允许换行。
基本语法:
.container { display: flex; flex-wrap: wrap;}| 属性值 | 说明 |
|---|---|
nowrap | 默认值,不换行 |
wrap | 允许换行 |
wrap-reverse | 允许换行,交叉轴的起止方向反转 |
注意:
nowrap并不代表子元素绝对不会超出容器,空间不足时,项目可能被压缩,也可能溢出。wrap只是允许换行,并不保证一定换行。- 当
flex-direction: column时,换行表现为排列到新的列,通常需要容器有明确的高度限制才能观察到
简写属性
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 wrap | 垂直排列,允许换列 |
flex-flow: row-reverse wrap | 水平反向排列,允许换行 |
注意: flex-flow 只负责排列方向和换行,与控制 Flex 项目自身伸缩的 flex 属性不同。
主轴对齐方式
justify-content 用于控制 Flex 项目在主轴方向上的对齐方式以及剩余空间分配。
基本语法:
.container { display: flex; justify-content: center;}| 属性值 | 说明 |
|---|---|
flex-start | 默认值,向主轴起点对齐 |
flex-end | 向主轴终点对齐 |
center | 在主轴上居中 |
space-between | 首尾项目贴近两端,其余空间分布在项目之间 |
space-around | 每个项目两侧分配相等空间,外侧间距为内部间距的一半 |
space-evenly | 所有相邻间距与两端间距相等 |
注意:
justify-content控制的是主轴,不一定是水平方向。- 当
flex-direction: column时,它控制垂直方向的对齐。 - 如果项目已经占满主轴可用空间,
space-between等空间分配方式可能看不出效果。 - 当存在多行项目时,
justify-content会分别作用于每一行。
交叉轴对齐方式
align-items 用于控制 Flex 项目在交叉轴方向上的对齐方式。
基本语法:
.container { display: flex; align-items: center;}| 属性值 | 说明 |
|---|---|
normal | 默认值,在常规 Flex 场景中通常表现为 stretch |
stretch | 在交叉轴尺寸为 auto 等适用条件下拉伸项目 |
flex-start | 向交叉轴起点对齐 |
flex-end | 向交叉轴终点对齐 |
center | 在交叉轴上居中 |
baseline | 沿项目的基线对齐,通常用于文字 |
注意:
align-items控制交叉轴,不一定是垂直方向。- 对多行 Flex 容器,它控制每一行内部项目的交叉轴对齐方式。
stretch不是无条件拉伸。如果项目已经设置固定高度(横向主轴时),通常不会被拉伸。
多行交叉轴对齐方式
align-content 用于控制 Flex 容器中多行项目在交叉轴方向上的整体排列及剩余空间分配。
与 align-items 不同,它操作的重点是多条 Flex 行,而不是每个项目自身。
基本语法:
.container { display: flex; flex-wrap: wrap; height: 300px; align-content: space-between;}| 属性值 | 说明 |
|---|---|
normal | 默认值,在 Flex 中通常表现为 stretch |
stretch | 拉伸 Flex 行以填充交叉轴的剩余空间 |
flex-start | 多行整体靠交叉轴起点 |
flex-end | 多行整体靠交叉轴终点 |
center | 多行整体在交叉轴居中 |
space-between | 首尾行靠两端,其余行均匀分布 |
space-around | 每行两侧分配相等空间 |
space-evenly | 各行间距与两端间距相等 |
注意:
- Flex 容器必须是多行,
align-content才能影响 Flex 行的排列。通常需要设置flex-wrap: wrap。 - 交叉轴方向需要有可供分配的剩余空间,才能明显观察
center、space-between等效果。 align-content: stretch拉伸的是 Flex 行,项目是否随之拉伸还受到align-items和项目尺寸的影响。
align-items 和 align-content 的区别
这是 Flex 布局中比较容易混淆的两个属性。
| 对比 | align-items | align-content |
|---|---|---|
| 主要控制对象 | 每条 Flex 行内的项目 | 整体的 Flex 行 |
| 作用方向 | 交叉轴 | 交叉轴 |
| 是否要求多行 | 否 | 是 |
| 典型用途 | 项目垂直居中 | 多行内容整体垂直居中 |
例如:
.container { display: flex; flex-flow: row wrap; height: 300px;
/* 每一行内部项目居中 */ align-items: center;
/* 所有行作为整体居中 */ align-content: center;}两者可以同时设置,作用并不冲突。
记忆方式
flex-direction:决定往哪个方向排。flex-wrap:决定排不下是否换行。flex-flow:前面两个属性的简写。justify-content:控制主轴上的对齐。align-items:控制交叉轴上每行项目的对齐。align-content:控制交叉轴上多行项目的整体分布。
实际开发中,最常使用的是 flex-direction、justify-content、align-items 和 flex-wrap。其中 align-content 通常在多行布局中才需要重点考虑。
Flex项目的属性
排列顺序:order
order 用于控制 Flex 项目的视觉排列顺序,数值越小,排列越靠前。
基本语法:
.item { order: 0;}| 属性值 | 说明 |
|---|---|
0 | 默认值 |
| 正整数 | 数值越大,排列越靠后 |
| 负整数 | 数值越小,排列越靠前 |
示例:
.item1 { order: 2;}
.item2 { order: 0;}
.item3 { order: -1;}注意: order 只影响视觉顺序,不会改变 HTML 中的 DOM 顺序,也不会相应改变键盘焦点和通常的屏幕阅读器阅读顺序,因此不应该用它替代有语义要求的内容排序。
放大比例:flex-grow
flex-grow 用于控制 Flex 项目如何分配主轴方向上的剩余空间。
基本语法:
.item { flex-grow: 0;}| 属性值 | 说明 |
|---|---|
0 | 默认值,不主动分配剩余空间 |
1 | 参与剩余空间分配 |
2 | 在其他条件相同的情况下,分得 1 的两倍剩余空间 |
| 其他非负数 | 按增长因子分配剩余空间 |
示例:
.container { display: flex; width: 500px;}
.item { flex-basis: 100px;}
.item1 { flex-grow: 1;}
.item2 { flex-grow: 2;}
.item3 { flex-grow: 1;}三个项目的基础宽度都是 100px,容器宽度 500px,剩余空间为 200px。增长因子比例为 1 : 2 : 1,所以剩余空间分别分配 50px、100px、50px。
注意:
flex-grow分配的是剩余空间,并不是直接决定最终宽度比例。- 只有主轴有可分配的正剩余空间时,才会发生增长。
- 实际结果还受
flex-basis、min-width、max-width等条件影响。
缩小比例:flex-shrink
flex-shrink 用于控制 Flex 项目在主轴空间不足时如何收缩。
基本语法:
.item { flex-shrink: 1;}| 属性值 | 说明 |
|---|---|
1 | 默认值,允许收缩 |
0 | 不参与 Flex 收缩 |
2 | 相同基础尺寸等条件下,收缩分配权重是 1 的两倍 |
| 其他非负数 | 按收缩因子参与收缩 |
示例:
.container { display: flex; width: 450px;}
.item { width: 200px; flex-shrink: 1;}三个项目的原始宽度合计为 600px,但容器只有 450px。因此,满足收缩条件时,三个项目会分别缩小到 150px。
如果不希望项目被 Flex 收缩:
.item { width: 200px; flex-shrink: 0;}此时三个项目的宽度不会因 Flex 的收缩算法而减小,可能溢出容器。
注意:
flex-shrink默认值为1,这也是 Flex 项目宽度有时小于设置值的原因。- 收缩空间按
flex-shrink × flex-basis等规则计算,并不是单纯按flex-shrink数值比例缩小。 - Flex 项目默认的
min-width: auto可能阻止进一步收缩,必要时可设置min-width: 0。
基础尺寸:flex-basis
flex-basis 用于指定 Flex 项目在分配剩余空间或进行收缩之前的主轴基础尺寸。
基本语法:
.item { flex-basis: auto;}| 属性值 | 说明 |
|---|---|
auto | 默认值,通常参考主轴方向对应的 width 或 height,否则依据内容确定尺寸 |
100px | 主轴基础尺寸为 100px |
30% | 根据 Flex 容器相应主轴尺寸计算百分比基础尺寸 |
content | 根据项目内容确定基础尺寸 |
0 | 基础尺寸设为零,仍受最小尺寸等约束 |
示例:
.container { display: flex;}
.item { width: 200px; flex-basis: 100px;}当 flex-direction: row 时,flex-basis: 100px 会优先作为 Flex 项目的主轴基础宽度,而不是使用 width: 200px。
但最终宽度仍可能因为 Flex 伸缩和尺寸限制而发生变化。
注意:
- 主轴水平时,
flex-basis主要对应宽度。 - 主轴垂直时,
flex-basis主要对应高度。 flex-basis不等于最终尺寸,而是 Flex 布局计算的基础尺寸。
简写属性:flex
flex 是 flex-grow、flex-shrink 和 flex-basis 的简写属性。
基本语法:
.item { flex: 0 1 auto;}等价于:
.item { flex-grow: 0; flex-shrink: 1; flex-basis: auto;}常见写法
| 写法 | 等价含义 | 说明 |
|---|---|---|
flex: initial | 0 1 auto | 默认行为,不增长、允许收缩 |
flex: none | 0 0 auto | 不增长、不收缩 |
flex: auto | 1 1 auto | 基于自动基础尺寸进行伸缩 |
flex: 1 | 浏览器中通常展开为 1 1 0% | 参与弹性空间分配 |
flex: 2 | 浏览器中通常展开为 2 1 0% | xxxxxxxxxx /* 网站 Banner /.banner { height: 400px; background: url(“/images/banner.jpg”) center / cover no-repeat;}/ 卡片渐变背景 /.card { background: linear-gradient(135deg, #667eea, #764ba2);}/ 渐变文字 */.title { background: linear-gradient(to right, #00c6ff, #0072ff); background-clip: text; color: transparent;}css |
flex: 1 1 200px | 1 1 200px | 基础尺寸 200px,可增长、可收缩 |
单独对齐方式:align-self
align-self 用于控制单个 Flex 项目在交叉轴方向上的对齐方式,可以覆盖 Flex 容器设置的 align-items。
基本语法:
.item { align-self: auto;}| 属性值 | 说明 |
|---|---|
auto | 默认值,采用父级 align-items 的对齐方式 |
normal | 在普通 Flex 场景中通常表现为 stretch |
stretch | 满足条件时沿交叉轴拉伸 |
flex-start | 交叉轴起点对齐 |
flex-end | 交叉轴终点对齐 |
center | 交叉轴居中 |
baseline | 基线对齐 |
示例:
.container { display: flex; height: 200px; align-items: flex-start;}
.item2 { align-self: center;}
.item3 { align-self: flex-end;}注意:
align-self控制交叉轴,不能直接控制主轴上的单个项目对齐。align-self: auto是采用父容器的对齐方式,并不是通过 CSS 属性继承实现的。- 若项目在交叉轴上存在
auto外边距,可能覆盖align-self的对齐效果。
Flex 项目属性总结
| 属性 | 作用 | 默认值 |
|---|---|---|
order | 控制项目视觉排列顺序 | 0 |
flex-grow | 控制正剩余空间的分配 | 0 |
flex-shrink | 控制空间不足时的收缩 | 1 |
flex-basis | 指定伸缩计算前的基础尺寸 | auto |
flex | 前面三个伸缩属性的简写 | 0 1 auto |
align-self | 控制单个项目交叉轴对齐 | auto |
实际开发应该重点掌握什么?
这六个属性可以分为四类:
- 顺序控制:
order - 弹性尺寸控制:
flex-grow、flex-shrink、flex-basis、flex - 单独对齐:
align-self
其中,日常开发最值得重点掌握的是 flex、flex-shrink 和 align-self。
尤其需要理解:flex-grow 分配剩余空间,flex-shrink 处理空间不足,flex-basis 提供计算的基础尺寸。 这三个属性共同决定 Flex 项目在主轴方向上的最终尺寸,而不是彼此独立地控制宽高。
Flex实战
圣杯布局
github代码仓库:https://github.com/youzi177/css-layout-lab
慕课网首页改造
github代码仓库:https://github.com/youzi177/css-layout-lab
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!














