主题
grid 网格布局
为什么需要 grid 布局?
一维 vs 二维
flexbox:一维布局
css
.container {
display: flex;
flex-direction: row; /* 或 column */
}特点:沿单轴排列
- 主轴方向:水平或者垂直。
- 交叉轴:垂直于主轴。
- 换行:自动到下一行/列。
grid:二维布局
css
.container {
display: grid;
grid-template-columns: 200px 100px 200px; /* 列轨道 */
grid-template-rows: 100px 100px; /* 行轨道 */
}特点:行列双向控制
- 同时定义行和列。
- 精确的网格单元格。
- 元素可跨越多个格子。
⭐ grid 中的核心要素
- grid 容器:一旦声明,内部的 直接子元素 自动变成 grid 项。
- 网格轨道:内容就在轨道里排列。
- 行轨道:水平方向。
- 列轨道:垂直方向。
- 网格线
- 分割轨道的 坐标系
- n 列的网格 = n + 1 条“垂直”线
- n 行的网格 = n + 1 条“水平”线
定义网格蓝图
grid-template-columns
定义网格的 列轨道。
css
.container {
display: grid;
/* 定义 3 列:第一列 200px,第二列 占据一份剩余空间,第三列 200px */
grid-template-columns: 200px 1fr 200px;
}grid-template-rows
定义网格的 行轨道。
css
.container {
display: grid;
/* 定义 2 行:第一行高 100px,第二行高度由内容决定 */
grid-template-rows: 100px auto;
}gap
定义网格项之间的间距。
css
.container {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: 100px auto;
/* 行间距和列间距均为 10px */
gap: 10px;
/* 或者分别定义行间距和列间距 */
/* row-gap: 10px; */
/* column-gap: 15px; */
}轨道尺寸单位
固定单位:px、em、rem
- 提供可预测的、绝对的尺寸。
- 适用于固定侧边栏宽度、导航栏高度等场景。
相对单位:%、vw、vh
- 相对于容器或视口的尺寸。
- 善于创建与父容器紧密关联的布局。
自动单位:auto
- 由内容决定轨道尺寸。
- 遵循“内容优先”原则。
弹性单位:fr
代表网格中,剩余“可用空间”的一份。
示例:等宽三列布局
css
.container {
display: grid;
/* 两条列间隙:2 * 20px = 40px */
grid-template-columns:
calc((100% - 40px) / 3)
calc((100% - 40px) / 3)
calc((100% - 40px) / 3);
gap: 20px;
}css
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 20px;
}fr 的工作原理
css
.container {
display: grid;
width: 800px;
grid-template-columns: 200px 1fr 2fr;
gap: 20px;
}计算过程:
总宽度:800px
固定宽度:200px(第一列)
间距总和:40px(2个 gap x 20px)
剩余空间:800px - 200px - 40px = 560px
560px 是 1fr + 2fr 的总和
fr 总份数:1fr + 2fr = 3fr
1fr 大小:560px / 3 = 186.67px
最终分配:
- 第一列:200px(固定)
- 第二列:186.67px(1fr)
- 第三列:373.33px(2fr)
repeat() 函数
基础用法:
css
/* 传统写法 */
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
/* 使用 repeat() */
grid-template-columns: repeat(5, 1fr);复杂模式重复:
css
/* 传统写法 */
grid-template-columns: 100px 1fr 100px 1fr 100px 1fr;
/* 使用 repeat() */
grid-template-columns: repeat(3, 100px 1fr);与其他单位混合使用:
css
/* 传统写法 */
grid-template-columns: 50px 1fr 1fr 1fr 50px
/* 使用 repeat() */
grid-template-columns: 50px repeat(3, 1fr) 50px;精准控制布局
基于网格线的精准定位
css
.item {
/* 列方向定位 */
grid-column-start: 1; /* 从第 1 条垂直线开始 */
grid-column-end: 3; /* 到第 3 条垂直线结束 */
/* 行方向定位 */
grid-row-start: 2; /* 从第 2 条水平线开始 */
grid-row-end: 4; /* 到第 4 条水平线结束 */
}css
.item {
/* 列方向定位 */
grid-column: 1 / 3; /* 从第 1 条垂直线开始,到第 3 条垂直线结束 */
/* 行方向定位 */
grid-row: 2 / 4; /* 从第 2 条水平线开始,到第 4 条水平线结束 */
}负数索引技巧:
-1 代表最后一条线,-2 代表倒数第二条线,以此类推。
css
.item-full-width {
/* 从第一列延伸到最后一列 */
grid-column: 1 / -1;
}示例:3x3 网格布局
css
.container {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
}
.item-1 {
background-color: red;
grid-column: 1 / 3;
grid-row: 1 / 2;
}
.item-2 {
background-color: green;
grid-column: 1 / 3;
grid-row: 2 / 3;
}
.item-3 {
background-color: blue;
grid-column: 3 / -1;
grid-row: 1 / -1;
}span 关键字实现动态跨越
基本语法:
css
.item-a {
/* 从第 2 列开始,横跨 2 列 */
grid-column: 2 / span 2;
}
.item-b {
/* 自动放置,横跨 3 列 */
grid-column: span 3;
}span 的灵活性:
css
.responsive-item {
/* 在小屏幕上横跨 2 列 */
grid-column: span 2;
}
@media (min-width: 768px) {
.responsive-item {
/* 在大屏幕上横跨 4 列 */
grid-column: span 4;
}
}命名网格区域
grid-area:将元素分配到命名区域。grid-template-areas:定义网格区域布局。
css
.header {
grid-area: header;
}
.nav {
grid-area: nav;
}
.content {
grid-area: content;
}
.aside {
grid-area: aside;
}
.footer {
grid-area: footer;
}
.responsive-layout {
display: grid;
grid-template-areas:
'header'
'nav'
'content'
'aside'
'footer';
grid-template-columns: 1fr;
gap: 10px;
}
@media (min-width: 768px) {
.responsive-layout {
grid-template-areas:
'header header'
'nav content'
'aside aside'
'footer footer';
grid-template-columns: 200px 1fr;
gap: 10px;
}
}对齐
容器级对齐:控制网格在容器中的位置
当网格的总尺寸小于其容器尺寸时,控制整个网格在容器的位置
容器对齐属性:
justify-content:控制网格在 行轴(水平方向) 上对齐。align-content:控制网格在 列轴(垂直方向) 上对齐。
常见对齐值:
start:网格在容器的起始位置对齐。end:网格在容器的结束位置对齐。center:网格在容器中居中。space-around:轨道均匀分布,首尾距边缘为轨道间距的一半。space-between:轨道均匀分布,首位轨道紧贴容器边缘。space-evenly:完全均匀分布。
css
.container {
width: 600px;
height: 600px;
display: grid;
justify-content: center; /* 水平居中对齐 */
align-content: center; /* 垂直居中对齐 */
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
gap: 10px;
}项目级对齐:控制项目在单元格内的位置
控制 单个网格项目在其分配到的单元格内部 的位置
容器统一定义:
justify-items:控制 所有项目 在各自单元格内的 水平对齐。align-items: 控制 所有项目 在各自单元格内的 垂直对齐。
项目独立定义:
justify-self:控制 单个项目 在其单元格内的 水平对齐。会覆盖justify-items。align-self:控制 单个项目 在其单元格内的 垂直对齐。会覆盖align-items。
可选值:
start:项目在单元格的起始位置对齐。end:项目在单元格的结束位置对齐。center:项目在单元格中居中。stretch(默认值)项目拉伸以填满单元格。
css
.container {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
gap: 10px;
justify-items: center; /* 所有项目水平居中 */
align-items: center; /* 所有项目垂直居中 */
}
.item-special {
justify-self: start; /* 该项目水平靠左 */
align-self: end; /* 该项目垂直靠下 */
}grid 响应式技巧
minmax() 函数
minmax() 可以为轨道尺寸设定弹性边界。
css
minmax(min, max)min:轨道的最小尺寸,保证内容的可读性。max:轨道的最大尺寸,通常配合1fr等弹性单位。
基本示例:
css
.container {
display: grid;
grid-template-columns: minmax(200px, 1fr) 500px minmax(200px, 1fr);
}auto-fill 和 auto-fit 关键字
自动化布局的两种模式,这两个关键字都会在“可用空间”中尽可能地多创建指定尺寸的轨道,但在处理“剩余空间”的方式不同:
auto-fill保守填充- 用尽可能多的轨道填充容器。
- 保留空轨道作为空白区域。
- 适合希望保持轨道尺寸严格的场景。
auto-fit适应填满- 创建轨道后,折叠空轨道。
- 让现有网格项拉伸填满容器。
- 适合构建自适应卡片网格。
css
/* auto-fill */
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* auto-fit */
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));黄金组合
repeat()+minmax()+auto-*
自适应布局:
css
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 10px;
}