06. Flexbox 与 Grid 布局
Flexbox 和 Grid 是现代 CSS 布局的两大核心,它们让复杂布局变得简单高效。
一、Flexbox 弹性布局
1. 基础概念
┌─────────────────────────────────────┐
│ Main Axis(主轴) │
│ ┌──────┐ ┌─────┐ ┌─────┐ │
│ │ 1 │ │ 2 │ │ 3 │ ←─── │
│ │ │ │ │ │ │ Cross │
│ │ │ │ │ │ │ Axis │
│ └──────┘ └─────┘ └─────┘ (交叉轴)│
└─────────────────────────────────────┘
Container(容器) Items(项目)2. 容器属性
flex-direction(主轴方向)
css
.container {
flex-direction: row; /* 水平向右(默认) */
flex-direction: row-reverse; /* 水平向左 */
flex-direction: column; /* 垂直向下 */
flex-direction: column-reverse; /* 垂直向上 */
}flex-wrap(换行)
css
.container {
flex-wrap: nowrap; /* 不换行(默认) */
flex-wrap: wrap; /* 换行,第一行在上 */
flex-wrap: wrap-reverse; /* 换行,第一行在下 */
}flex-flow(简写)
css
.container {
/* flex-flow: flex-direction flex-wrap; */
flex-flow: row wrap;
}justify-content(主轴对齐)
css
.container {
justify-content: flex-start; /* 左对齐(默认) */
justify-content: flex-end; /* 右对齐 */
justify-content: center; /* 居中 */
justify-content: space-between; /* 两端对齐,间距相等 */
justify-content: space-around; /* 两端间距是中间的一半 */
justify-content: space-evenly; /* 所有间距完全相等 */
}align-items(交叉轴对齐)
css
.container {
align-items: stretch; /* 拉伸(默认) */
align-items: flex-start; /* 起点对齐 */
align-items: flex-end; /* 终点对齐 */
align-items: center; /* 居中 */
align-items: baseline; /* 基线对齐 */
}align-content(多行对齐)
css
.container {
align-content: stretch; /* 拉伸(默认) */
align-content: flex-start; /* 起点对齐 */
align-content: flex-end; /* 终点对齐 */
align-content: center; /* 居中 */
align-content: space-between; /* 两端对齐 */
align-content: space-around; /* 均匀分布 */
align-content: space-evenly; /* 完全均匀 */
}3. 项目属性
order(顺序)
css
.item {
order: 0; /* 默认 */
order: -1; /* 排到最前 */
order: 2; /* 排到后面 */
}flex-grow(放大比例)
css
.item {
flex-grow: 0; /* 不放大(默认) */
flex-grow: 1; /* 有剩余空间,放大 */
flex-grow: 2; /* 放大比例是 1 的 2 倍 */
}flex-shrink(缩小比例)
css
.item {
flex-shrink: 1; /* 缩小(默认) */
flex-shrink: 0; /* 不缩小 */
}flex-basis(基准大小)
css
.item {
flex-basis: auto; /* 自动(默认) */
flex-basis: 200px; /* 固定基准 */
}flex(简写)
css
.item {
/* flex: flex-grow flex-shrink flex-basis; */
flex: 1; /* flex: 1 1 0% */
flex: auto; /* flex: 1 1 auto */
flex: none; /* flex: 0 0 auto */
flex: 0 0 200px; /* 不放大不缩小,固定 200px */
}align-self(单独对齐)
css
.item {
align-self: auto; /* 继承容器(默认) */
align-self: flex-start;
align-self: flex-end;
align-self: center;
align-self: baseline;
align-self: stretch;
}二、Grid 网格布局
1. 基础概念
┌─────────┬─────────┬─────────┬─────────┐
│ Grid │ Cell │ Cell │ Cell │
│ Row ├─────────┼─────────┼─────────┤
├─────────┤ Cell │ Cell │ Cell │
│ Grid ├─────────┼─────────┼─────────┤
│ Row │ Cell │ Cell │ Cell │
├─────────┼─────────┼─────────┼─────────┤
│ Grid │ Cell │ Cell │ Cell │
│ Row └─────────┴─────────┴─────────┘
└───────────────────────────────────────┘
Grid Lines(网格线)2. 容器属性
display(启用 Grid)
css
.container {
display: grid;
display: inline-grid;
}grid-template-columns(列定义)
css
.container {
/* 固定宽度 */
grid-template-columns: 100px 200px 100px;
/* 重复 */
grid-template-columns: repeat(3, 100px);
/* 百分比 */
grid-template-columns: 33.33% 33.33% 33.33%;
/* fr(fraction,占据剩余空间) */
grid-template-columns: 1fr 1fr 1fr;
grid-template-columns: 1fr 2fr 1fr;
/* auto(自适应) */
grid-template-columns: 1fr auto 1fr;
/* minmax(最小最大) */
grid-template-columns: 1fr minmax(100px, 1fr) 2fr;
/* 自动填充 */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* 自动填充+合适 */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}grid-template-rows(行定义)
css
.container {
grid-template-rows: 100px 200px 100px;
grid-template-rows: repeat(3, auto);
}grid-template-areas(区域命名)
css
.container {
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
}
.item {
grid-area: header;
grid-area: sidebar;
grid-area: main;
grid-area: footer;
}grid-template(简写)
css
.container {
grid-template:
"header header header" 80px
"sidebar main main" 1fr
"footer footer footer" 60px /
200px 1fr 1fr;
}gap(间距)
css
.container {
gap: 10px; /* 行列相同 */
row-gap: 10px; /* 行间距 */
column-gap: 20px; /* 列间距 */
gap: 10px 20px; /* 行 10px,列 20px */
}justify-items(水平对齐)
css
.container {
justify-items: stretch; /* 拉伸(默认) */
justify-items: start;
justify-items: end;
justify-items: center;
}align-items(垂直对齐)
css
.container {
align-items: stretch; /* 拉伸(默认) */
align-items: start;
align-items: end;
align-items: center;
}justify-content(整体水平对齐)
css
.container {
justify-content: start;
justify-content: end;
justify-content: center;
justify-content: space-between;
justify-content: space-around;
justify-content: space-evenly;
}align-content(整体垂直对齐)
css
.container {
align-content: start;
align-content: end;
align-content: center;
align-content: space-between;
align-content: space-around;
align-content: space-evenly;
}place-items(简写)
css
.container {
place-items: center; /* align-items + justify-items */
}3. 项目属性
grid-column(列位置)
css
.item {
/* 从第1条线开始,到第3条线结束 */
grid-column: 1 / 3;
/* 从第1条线开始,跨越2列 */
grid-column: 1 / span 2;
/* 简写 */
grid-column-start: 1;
grid-column-end: 3;
}grid-row(行位置)
css
.item {
grid-row: 1 / 3;
grid-row: 1 / span 2;
}grid-area(区域)
css
.item {
grid-area: header;
/* 等价于 */
grid-row-start: 1;
grid-column-start: 1;
grid-row-end: 2;
grid-column-end: 4;
}justify-self(单独水平对齐)
css
.item {
justify-self: start;
justify-self: end;
justify-self: center;
}align-self(单独垂直对齐)
css
.item {
align-self: start;
align-self: end;
align-self: center;
}三、Flexbox vs Grid
| 特性 | Flexbox | Grid |
|---|---|---|
| 维度 | 一维(行或列) | 二维(行和列) |
| 适用场景 | 导航、对齐、弹性布局 | 页面整体布局、网格系统 |
| 溢出处理 | 自动换行 | 需要显式定义 |
| 浏览器支持 | 更好的兼容性 | 较新的浏览器 |
选择建议
- 使用 Flexbox:导航栏、对齐元素、弹性组件
- 使用 Grid:页面布局、网格系统、卡片布局
- 结合使用:Grid 负责大布局,Flexbox 负责内部对齐
四、实际案例
1. 水平垂直居中
css
/* Flexbox */
.container {
display: flex;
align-items: center;
justify-content: center;
}
/* Grid */
.container {
display: grid;
place-items: center;
}2. 均分列
css
/* Flexbox */
.container {
display: flex;
}
.item {
flex: 1;
}
/* Grid */
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}3. 圣杯布局
css
.container {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 60px 1fr 60px;
grid-template-areas:
"header header header"
"sidebar main ads"
"footer footer footer";
min-height: 100vh;
}4. 响应式网格
css
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
/* 自动适应,不小于250px,平分剩余空间 */
}5. 卡片悬停效果
css
.container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 20px;
}
.card {
transition: transform 0.3s;
}
.card:hover {
transform: translateY(-5px);
}五、浏览器兼容性
css
/* 前缀 */
.container {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
display: -webkit-grid;
display: -ms-grid;
display: grid;
}
/* 检测支持 */
@supports (display: grid) {
/* Grid 支持代码 */
}
@supports (display: flex) {
/* Flexbox 支持代码 */
}总结
Flexbox 适合一维布局,Grid 适合二维布局。掌握这两种布局方式可以解决大部分布局需求,建议根据实际场景选择最合适的方案。