Flexbox 弹性盒布局
CoreCSS LayoutFlexbox(Flexible Box Layout)是专为 一维布局 设计的 CSS 工具,用于在一条轴线上对齐和分配容器内子元素的空间。它取代了早期使用 table、float、inline-block 等进行页面布局的 hack 方式。
一、📜 布局方式的演进
在 Flexbox 出现之前,开发者经历了多种布局方式:
| 时代 | 方式 | 问题 |
|---|---|---|
| ~2000 | HTML <table> 布局 | 语义错误,table 应只用于表格数据 |
| ~2005 | display: inline-block | 对齐困难,间距需要 hack |
| ~2005–2010 | position: absolute | 不灵活,不响应式 |
| ~2005–2010 | float + clear | 各种 hack(clearfix 等),难以维护 |
| 现代 | Flexbox / Grid | 专为布局设计,简洁强大 |
Float 不应用于布局
float 的设计初衷是让文本环绕图片。用它做页面布局是 hack 行为。现代开发中,布局请使用 Flexbox 或 Grid。
二、🚀 Display Flex 基础
2.1 启用 Flexbox
只需在 容器(父元素)上设置 display: flex:
.container {
display: flex;
}<div class="container">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>效果:所有子元素自动排成一行,宽度基于各自的 内容尺寸。
2.2 核心概念
| 概念 | 说明 |
|---|---|
| Flex Container(容器) | 设置了 display: flex 的父元素 |
| Flex Items(项目) | 容器内的直接子元素 |
| 独立系统 | 启用 flex 后,子元素原有的 display: block/inline 规则被 全部忽略 |
| 内容驱动宽度 | 每个项目的宽度默认由其内容决定 |
2.3 Gap 属性
在项目之间添加间距:
.container {
display: flex;
gap: 10px; /* 固定间距 */
gap: 1rem; /* 响应式间距(推荐) */
}2.4 Flex vs Inline-flex
| 值 | 容器宽度 | 类比 |
|---|---|---|
display: flex | 100% 宽度(类似 block) | 独占一行 |
display: inline-flex | 仅占内容所需宽度(类似 inline-block) | 与其他元素同行 |
三、🧭 Flex Direction(方向)
flex-direction 决定 主轴的方向,即项目的排列方向:
.container {
flex-direction: row; /* 默认:从左到右 */
flex-direction: column; /* 从上到下 */
}3.1 主轴与交叉轴
这是 Flexbox 最核心的概念——所有对齐属性都基于轴的方向:
| flex-direction | 主轴 (Main Axis) | 交叉轴 (Cross Axis) |
|---|---|---|
row(默认) | ← 水平 → | ↑ 垂直 ↓ |
column | ↑ 垂直 ↓ | ← 水平 → |
flex-direction: row
主轴 (Main Axis)
─────────────────────────→
┌──────┐ ┌──────┐ ┌──────┐
│ 1 │ │ 2 │ │ 3 │ 交叉轴
└──────┘ └──────┘ └──────┘ (Cross)
↓
flex-direction: column
↓ 主轴 → 交叉轴
┌──────┐
│ 1 │
├──────┤
│ 2 │
├──────┤
│ 3 │
└──────┘3.2 Flex Basis
flex-basis 设置项目沿 主轴 的初始尺寸:
.item {
flex-basis: 100px;
}| flex-direction | flex-basis 控制的维度 |
|---|---|
row | 宽度 |
column | 高度 |
flex-basis 是子元素属性
flex-basis 设置在 项目(子元素)上,不是容器上。这与 display: flex、gap 等容器属性不同。
3.3 选中直接子元素
使用 子代组合选择器 > 配合 通配符 * 来选中所有 flex 项目:
.container > * {
flex-basis: 100px; /* 所有直接子元素 */
}四、📐 Flex 布局属性
4.1 容器属性(设置在父元素上)
Flex Wrap(换行)
.container {
flex-wrap: nowrap; /* 默认:不换行,溢出被隐藏 */
flex-wrap: wrap; /* 换行:放不下的项目移到下一行 */
flex-wrap: wrap-reverse; /* 反向换行 */
}注意拼写
是 nowrap(无连字符),不是 no-wrap。
Justify Content(主轴分布)
控制项目在 主轴 上的分布方式:
.container {
justify-content: flex-start; /* 起端对齐(默认) */
justify-content: flex-end; /* 末端对齐 */
justify-content: center; /* 居中 */
justify-content: space-between; /* 首尾贴边,中间均分 */
justify-content: space-around; /* 每个项目两侧等间距 */
justify-content: space-evenly; /* 所有间距完全相等 */
}space-between: |■ ■ ■|
space-around: | ■ ■ ■ |
space-evenly: | ■ ■ ■ |Align Items(交叉轴对齐)
控制项目在 交叉轴 上的对齐方式:
.container {
height: 70vh; /* 需要容器有足够高度 */
align-items: flex-start; /* 顶部对齐 */
align-items: flex-end; /* 底部对齐 */
align-items: center; /* 垂直居中 */
align-items: stretch; /* 拉伸填满(默认) */
align-items: baseline; /* 基线对齐 */
}居中的最简方式
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}只需这四行,即可让内容在页面上 水平 + 垂直居中。
Align Content(多行对齐)
仅在 flex-wrap: wrap 时生效,控制 多行 在交叉轴上的分布:
.container {
flex-wrap: wrap;
align-content: center; /* 多行整体居中 */
align-content: space-between; /* 行间均分 */
align-content: flex-start; /* 顶部对齐 */
}4.2 项目属性(设置在子元素上)
Order(排列顺序)
.green-item {
order: 1; /* 默认所有项目 order: 0,数值越大越靠后 */
}Align Self(单独对齐)
覆盖容器的 align-items,让单个项目独立对齐:
.special-item {
align-self: flex-start; /* 即使容器 align-items: center,此项目靠顶部 */
}五、📊 Flex Sizing(尺寸控制)
5.1 尺寸优先级
Flexbox 按以下优先级决定项目尺寸(从高到低):
❶ min-width / max-width(最高优先级)
↓
❷ flex-basis
↓
❸ width / height
↓
❹ 内容宽度(Content Width)(最低优先级)5.2 内容宽度(默认行为)
不设任何尺寸属性时:
- 最大宽度 = 所有内容在一行时的宽度
- 最小宽度 = 最长单词的宽度(文本不会断词)
- 缩小窗口时,项目会从最大宽度 收缩 到最小宽度
5.3 width vs flex-basis
.item {
width: 100px; /* 较低优先级 */
flex-basis: 200px; /* 较高优先级,会覆盖 width */
}当同时设置 width 和 flex-basis 时,flex-basis 胜出。
5.4 min-width 与 max-width
.item {
flex-basis: 200px;
max-width: 100px; /* 限制最大宽度为 100px → 优先于 flex-basis */
}
.item {
flex-basis: 200px;
min-width: 300px; /* 限制最小宽度为 300px → 优先于 flex-basis */
}5.5 Flex Grow 与 Flex Shrink
| 属性 | 默认值 | 作用 |
|---|---|---|
flex-grow | 0 | 是否 扩展 以占满剩余空间 |
flex-shrink | 1 | 是否 收缩 以适应不足空间 |
/* 关闭增长和收缩 → 固定尺寸 */
.item { flex-grow: 0; flex-shrink: 0; flex-basis: 100px; }
/* 允许增长、不允许收缩 */
.item { flex-grow: 1; flex-shrink: 0; flex-basis: 100px; }
/* 不允许增长、允许收缩(默认行为) */
.item { flex-grow: 0; flex-shrink: 1; flex-basis: auto; }
/* 允许增长和收缩(最灵活) */
.item { flex-grow: 1; flex-shrink: 1; flex-basis: 0; }5.6 Flex 简写
/* flex: grow shrink basis */
.item { flex: 1 1 0; }
/* 最常用简写 — 等价于 flex: 1 1 0 */
.item { flex: 1; }5.7 比例布局
通过不同的 flex 值设置 比例关系:
.red { flex: 1; } /* 1/6 的宽度 */
.blue { flex: 2; } /* 2/6 的宽度 */
.green { flex: 3; } /* 3/6 的宽度 */无论窗口如何缩放,三者始终保持 1:2:3 的比例。
六、📋 Flexbox 速查表
容器属性(Parent)
| 属性 | 常用值 | 作用 |
|---|---|---|
display | flex / inline-flex | 启用弹性盒 |
flex-direction | row / column | 主轴方向 |
flex-wrap | nowrap / wrap | 是否换行 |
justify-content | center / space-between / space-evenly | 主轴分布 |
align-items | center / stretch / flex-start | 交叉轴对齐 |
align-content | center / space-between | 多行对齐(需 wrap) |
gap | 10px / 1rem | 项目间距 |
项目属性(Child)
| 属性 | 常用值 | 作用 |
|---|---|---|
order | 0(默认) | 排列顺序 |
flex-basis | auto / 100px / 0 | 初始尺寸 |
flex-grow | 0(默认) / 1 | 是否扩展 |
flex-shrink | 1(默认) / 0 | 是否收缩 |
flex | 1 / 1 1 0 | 简写(grow shrink basis) |
align-self | center / flex-start | 独立交叉轴对齐 |
七、🧪 实战:定价表(Pricing Table)
核心布局
.pricing-container {
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
height: 100vh; /* 满屏居中 */
}
.pricing-plan {
flex: 1;
max-width: 400px; /* 限制最大宽度 */
padding: 1.5rem;
background-color: #f5f5f5;
border-radius: 5px;
text-align: center;
}响应式处理(Media Query)
@media (max-width: 1250px) {
.pricing-container {
flex-direction: column; /* 窄屏时纵向堆叠 */
height: 100%; /* 取消固定高度,适应内容 */
}
}Flexbox + Media Query = 响应式
通过在 media query 中将 flex-direction 从 row 切换为 column,即可轻松实现桌面横排、移动端纵排的响应式布局。
八、🎮 练习资源
| 资源 | 地址 | 说明 |
|---|---|---|
| Flexbox Froggy | flexboxfroggy.com | 交互式闯关游戏,推荐使用 Intermediate 难度 |
| CSS Tricks Cheat Sheet | css-tricks.com/snippets/css/a-guide-to-flexbox | 最权威的 Flexbox 可视化参考 |