Grid 容器属性:掌控网格布局的核心
想象你是一个城市规划师,需要设计一个新城区的街道布局。你需要决定有多少条大街(列),有多少条小巷(行),街道有多宽,建筑之间的间距有多大,以及建筑在地块中如何对齐。Grid 容器属性就像是你手中的规划工具,让你可以精确控制整个网格的结构和布局规则。
在上一章中,我们了解了 Grid 布局的基本概念。现在,让我们深入学习 Grid 容器的各种属性,它们是控制整个网格布局的核心。
定义网格结构
首先,我们需要定义网格的基本结构——有多少列、有多少行、每列多宽、每行多高。
grid-template-columns:定义列结构
grid-template-columns 属性定义网格有多少列,以及每列的宽度。这是 Grid 布局中最重要的属性之一。
固定宽度列
最简单的方式是使用固定宽度:
.grid {
display: grid;
grid-template-columns: 200px 300px 400px; /* 三列,宽度分别是 200px、300px、400px */
}如果容器宽度是 900px,这三列刚好填满。如果容器更宽,右边会留下空白;如果容器更窄,网格会溢出。
弹性 fr 单位
fr 单位让网格变得弹性,它表示"可用空间的一份":
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* 三列平分空间 */
}假设容器宽度是 900px:
- 总共 3 份(1 + 1 + 1)
- 每份 = 900px ÷ 3 = 300px
- 三列都是 300px
你可以使用不同的 fr 值创建不同的比例:
.grid {
display: grid;
grid-template-columns: 2fr 1fr 1fr; /* 第一列是其他列的两倍 */
}假设容器宽度是 900px:
- 总共 4 份(2 + 1 + 1)
- 每份 = 900px ÷ 4 = 225px
- 第一列:225px × 2 = 450px
- 第二列:225px
- 第三列:225px
混合使用不同单位
Grid 的强大之处在于可以混合使用不同单位:
.grid {
display: grid;
grid-template-columns: 200px 1fr 2fr 150px;
/* 固定 + 弹性 + 弹性 + 固定 */
}假设容器宽度是 900px:
- 先分配固定宽度:200px + 150px = 350px
- 剩余空间:900px - 350px = 550px
- 弹性空间总份数:1 + 2 = 3 份
- 每份:550px ÷ 3 ≈ 183.3px
- 最终分配:
- 第一列:200px(固定)
- 第二列:183.3px(1 份)
- 第三列:366.7px(2 份)
- 第四列:150px(固定)
这种混合方式非常适合创建"侧边栏 + 弹性内容 + 侧边栏"的布局。
minmax() 函数
minmax() 函数定义列的最小和最大值:
.grid {
display: grid;
grid-template-columns: minmax(200px, 300px) 1fr 1fr;
/* 第一列:最小 200px,最大 300px */
}这很有用,因为你可以确保列不会太窄(小于 200px)也不会太宽(大于 300px)。
实际效果:
- 如果容器很宽,第一列会达到 300px,然后停止增长,剩余空间被其他列平分
- 如果容器很窄,第一列会保持 200px 的最小宽度
常见的用法是设置最小值,最大值用 fr:
.grid {
display: grid;
grid-template-columns: minmax(200px, 1fr) minmax(200px, 1fr) minmax(200px, 1fr);
/* 每列最小 200px,然后平分空间 */
}这确保每列至少有 200px,但在宽屏幕上会平均分配额外的空间。
auto 关键字
auto 关键字让列根据内容自动调整大小:
.grid {
display: grid;
grid-template-columns: auto 1fr auto;
/* 第一列和第三列根据内容调整,第二列占据剩余空间 */
}这在创建导航栏时特别有用:
<nav class="navbar">
<div class="logo">TechCorp</div>
<div class="spacer"></div>
<div class="nav-links">Home Products About Contact</div>
</nav>.navbar {
display: grid;
grid-template-columns: auto 1fr auto;
/* logo 和 nav-links 根据内容大小,中间的 spacer 填充剩余空间 */
align-items: center;
background-color: #333;
padding: 15px 30px;
}
.logo {
color: white;
font-size: 24px;
font-weight: bold;
}
.nav-links {
color: white;
}repeat() 函数
当有很多相同的列时,repeat() 函数让代码更简洁:
/* 传统写法 */
.grid {
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr;
}
/* 使用 repeat() */
.grid {
display: grid;
grid-template-columns: repeat(6, 1fr);
/* 重复 6 次 1fr */
}repeat() 可以重复一个模式:
.grid {
display: grid;
grid-template-columns: repeat(3, 100px 200px);
/* 创建 6 列:100px 200px 100px 200px 100px 200px */
}auto-fill 和 auto-fit
这两个关键字配合 repeat() 使用,可以创建响应式的列:
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, 200px);
/* 自动填充尽可能多的 200px 宽的列 */
}假设容器宽度是 850px:
- 能放下 4 列(4 × 200px = 800px)
- 剩余 50px 留白
auto-fit 与 auto-fill 类似,但会收缩空列:
.grid-fill {
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* auto-fill:会保留空列 */
}
.grid-fit {
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
/* auto-fit:会收缩空列,让存在的列占据更多空间 */
}实际应用:
.card-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}这会创建一个完全响应式的卡片布局:
- 每张卡片最小 250px
- 容器宽度够大时,卡片会平分空间
- 容器变窄时,会自动减少列数
- 完全不需要媒体查询!
grid-template-rows:定义行结构
grid-template-rows 的用法与 grid-template-columns 完全相同,只是它定义的是行而不是列。
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: 100px 200px 150px; /* 三行,高度分别是 100px、200px、150px */
}隐式网格和 grid-auto-ros
Grid 有一个聪明的特性:如果项目数量超过了你定义的网格单元,Grid 会自动创建新行。这些新行被称为"隐式网格行"。
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 3 列 */
grid-template-rows: 150px; /* 只定义第一行 150px */
grid-auto-rows: 100px; /* 隐式行的高度是 100px */
}如果有 10 个项目:
- 前 3 个在第一行(高度 150px)
- 第 4-6 个在第二行(高度 100px,隐式行)
- 第 7-9 个在第三行(高度 100px,隐式行)
- 第 10 个在第四行(高度 100px,隐式行)
使用 auto 让行高度根据内容自动调整:
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: auto; /* 行高度根据内容自动调整 */
}或者使用 minmax() 设置最小和最大高度:
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: minmax(100px, auto);
/* 每行最小 100px,最大根据内容 */
}这确保每行至少有 100px 高,但如果内容更多,行会自动扩展。
间距控制
gap:项目之间的间距
gap 属性(以前叫 grid-gap)控制网格项目之间的间距。它是一个简写属性。
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px; /* 行间距和列间距都是 20px */
}你也可以分别设置行间距和列间距:
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px 30px; /* 行间距 20px,列间距 30px */
/* 或者使用单独的属性: */
/* row-gap: 20px; */
/* column-gap: 30px; */
}重要提示: gap 只在项目之间创建间距,不会在容器边缘创建间距。如果你需要容器边缘也有间距,使用 padding:
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px; /* 项目之间 20px */
padding: 20px; /* 容器边缘也有 20px */
}对齐控制
Grid 提供了强大的对齐控制,可以精确控制项目在单元格中的位置。
justify-items:水平方向对齐
justify-items 控制所有网格项目在其单元格中的水平对齐方式。
.grid {
display: grid;
grid-template-columns: repeat(3, 200px);
justify-items: start; /* 默认值:项目靠左对齐 */
}可能的值:
start:靠左对齐(默认)end:靠右对齐center:水平居中stretch:拉伸填充整个单元格的宽度
/* 示例:居中对齐 */
.grid {
display: grid;
grid-template-columns: repeat(3, 200px);
justify-items: center; /* 所有项目在单元格中水平居中 */
}
.item {
width: 100px; /* 项目宽度小于单元格宽度 200px */
background-color: #2196f3;
}
/* 每个项目都会在其 200px 的单元格中居中显示 *//* 示例:拉伸 */
.grid {
display: grid;
grid-template-columns: repeat(3, 200px);
justify-items: stretch; /* 项目拉伸填充单元格 */
}
.item {
/* 不要设置 width,否则 stretch 不生效 */
background-color: #2196f3;
}
/* 每个项目都会拉伸到 200px 宽 */align-items:垂直方向对齐
align-items 控制所有网格项目在其单元格中的垂直对齐方式。
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 150px; /* 每行 150px */
align-items: start; /* 项目靠上对齐 */
}可能的值:
start:靠上对齐end:靠下对齐center:垂直居中stretch:拉伸填充整个单元格的高度(默认)
/* 实用示例:完美居中 */
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 150px;
justify-items: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
gap: 20px;
}
/* 所有项目都会在其单元格中完美居中 */place-items:对齐方式简写
place-items 是 align-items 和 justify-items 的简写:
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
place-items: center center;
/* 相当于: */
/* align-items: center; */
/* justify-items: center; */
}如果只写一个值,两个方向都使用这个值:
.grid {
place-items: center;
/* 相当于: */
/* align-items: center; */
/* justify-items: center; */
}justify-content:整个网格的水平对齐
前面的 justify-items 控制项目在单元格中的对齐。justify-content 则控制整个网格在容器中的水平对齐。
这在网格总宽度小于容器宽度时非常有用:
.grid {
display: grid;
grid-template-columns: repeat(3, 200px); /* 总宽度 600px */
width: 900px; /* 容器宽度 900px */
justify-content: start; /* 默认:网格靠左 */
}可能的值:
start:靠左对齐(默认)end:靠右对齐center:居中stretch:列拉伸以填充容器space-between:第一列靠左,最后一列靠右,中间列平分剩余空间space-around:每列两侧有相等的空间space-evenly:所有间距相等
/* 示例:space-between */
.grid {
display: grid;
grid-template-columns: repeat(3, 200px);
width: 900px;
justify-content: space-between;
background-color: #f5f5f5;
padding: 20px;
}
/* 第一列贴左边,最后一列贴右边,中间有 150px 空隙 */align-content:整个网格的垂直对齐
align-content 控制整个网格在容器中的垂直对齐,当网格总高度小于容器高度时使用。
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 100px); /* 总高度 200px */
height: 500px; /* 容器高度 500px */
align-content: center; /* 网格垂直居中 */
}可能的值与 justify-content 相同:start、end、center、stretch、space-between、space-around、space-evenly。
place-content:content 对齐简写
place-content 是 align-content 和 justify-content 的简写:
.grid {
display: grid;
grid-template-columns: repeat(3, 150px);
grid-template-rows: repeat(2, 100px);
width: 600px;
height: 400px;
place-content: center center;
/* 整个网格在容器中水平和垂直都居中 */
}grid-auto-flow:控制自动放置
grid-auto-flow 控制项目的自动放置方向。
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-flow: row; /* 默认值:按行填充 */
}可能的值:
row(默认):按行填充,从左到右,然后下一行column:按列填充,从上到下,然后下一列dense:尝试填充网格中的空洞
/* 按列填充 */
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 100px);
grid-auto-flow: column;
}
/* 项目会按列填充:
1 4 7
2 5 8
3 6 9
*/dense 关键字会尝试填充网格中的空洞:
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-flow: dense;
}
.item-wide {
grid-column: span 2; /* 占据 2 列 */
}如果某个宽项目放不下当前行的剩余空间,dense 会让后面的小项目先填充空位,而不是留下空白。
实际应用示例
让我们把这些属性组合起来,创建一些实用的布局。
响应式作品集
<div class="portfolio">
<div class="project project-featured">Featured Project</div>
<div class="project">Project 2</div>
<div class="project">Project 3</div>
<div class="project">Project 4</div>
<div class="project">Project 5</div>
<div class="project">Project 6</div>
</div>.portfolio {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
/* 响应式列:最小 300px,自动调整列数 */
grid-auto-rows: 250px;
/* 每行 250px */
gap: 20px;
padding: 20px;
}
.project {
background-color: #e3f2fd;
border-radius: 8px;
padding: 20px;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
transition: transform 0.3s;
}
.project:hover {
transform: scale(1.05);
}
.project-featured {
grid-column: span 2; /* 占据 2 列 */
grid-row: span 2; /* 占据 2 行 */
background-color: #2196f3;
color: white;
font-size: 24px;
}这个布局会:
- 在宽屏幕上显示多列
- 在窄屏幕上自动减少列数
- 特色项目占据 2×2 的空间
- 完全响应式,无需媒体查询
仪表板布局
.dashboard {
display: grid;
grid-template-columns: repeat(12, 1fr); /* 12 列系统 */
grid-auto-rows: minmax(100px, auto);
gap: 20px;
padding: 20px;
}
.header {
grid-column: 1 / 13; /* 占据所有 12 列 */
background-color: #333;
color: white;
padding: 20px;
}
.sidebar {
grid-column: 1 / 3; /* 占据 2 列 */
grid-row: 2 / 5; /* 占据 3 行 */
background-color: #f5f5f5;
padding: 20px;
}
.main-widget {
grid-column: 3 / 9; /* 占据 6 列 */
grid-row: 2 / 4; /* 占据 2 行 */
background-color: #2196f3;
color: white;
padding: 30px;
}
.stats {
grid-column: 9 / 13; /* 占据 4 列 */
background-color: #e3f2fd;
padding: 20px;
}
.chart {
grid-column: 3 / 9;
background-color: white;
border: 1px solid #ddd;
padding: 20px;
}
.recent {
grid-column: 9 / 13;
grid-row: 3 / 5;
background-color: white;
border: 1px solid #ddd;
padding: 20px;
}总结
Grid 容器属性给了你完全的布局控制权。让我们回顾一下核心属性:
定义结构:
grid-template-columns:定义列结构grid-template-rows:定义行结构grid-auto-rows:定义隐式行的大小grid-auto-flow:控制自动放置方向
间距控制:
gap:项目之间的间距(简写)row-gap:行间距column-gap:列间距
项目对齐:
justify-items:项目在单元格中的水平对齐align-items:项目在单元格中的垂直对齐place-items:对齐简写
网格对齐:
justify-content:整个网格在容器中的水平对齐align-content:整个网格在容器中的垂直对齐place-content:对齐简写
关键技巧:
- 使用
fr单位创建弹性列 - 使用
minmax()设置尺寸范围 - 使用
repeat()简化重复模式 - 使用
auto-fit和auto-fill创建响应式布局 - 混合使用固定和弹性单位获得最大灵活性
掌握这些容器属性,你就能创建任何你想要的网格布局。在下一节中,我们将学习 Grid 项目属性,它们让你可以精确控制单个项目在网格中的位置和大小。