CSS 网格布局
网格布局(Grid Layout)是CSS3中引入的一种二维布局模型,用于在容器内同时对行和列进行布局。Grid布局使得创建复杂的二维布局变得更加容易。
基本概念
1. Grid容器(Grid Container)
通过设置display: grid或display: inline-grid将元素转换为Grid容器:
.container {
display: grid; /* 块级Grid容器 */
/* 或 */
display: inline-grid; /* 行内Grid容器 */
}
2. Grid项目(Grid Items)
Grid容器内的直接子元素称为Grid项目:
<div class="container">
<div class="item">项目1</div> <!-- Grid项目 -->
<div class="item">项目2</div> <!-- Grid项目 -->
<div class="item">项目3</div> <!-- Grid项目 -->
<div class="item">项目4</div> <!-- Grid项目 -->
</div>
3. Grid线(Grid Lines)
Grid线是网格的分隔线,包括水平线和垂直线:
- 水平线:从上到下编号为1, 2, 3…
- 垂直线:从左到右编号为1, 2, 3…
4. Grid轨道(Grid Tracks)
Grid轨道是两条相邻Grid线之间的空间,包括行轨道和列轨道:
- 行轨道:水平方向的空间
- 列轨道:垂直方向的空间
5. Grid单元格(Grid Cells)
Grid单元格是行轨道和列轨道的交叉区域,是Grid布局的最小单位。
6. Grid区域(Grid Areas)
Grid区域是由多个Grid单元格组成的矩形区域。
容器属性
1. grid-template-columns
grid-template-columns属性定义了列轨道的大小:
.container {
grid-template-columns: <轨道大小>...;
}
例如:
.container {
grid-template-columns: 100px 200px 300px; /* 三列,宽度分别为100px、200px、300px */
}
常用的轨道大小单位:
- 固定长度:px、em等
- 百分比:%
- 弹性长度:fr(fraction,剩余空间的分数)
- auto:自动计算大小
例如:
.container {
grid-template-columns: 1fr 2fr 1fr; /* 三列,比例为1:2:1 */
}
2. grid-template-rows
grid-template-rows属性定义了行轨道的大小:
.container {
grid-template-rows: <轨道大小>...;
}
例如:
.container {
grid-template-rows: 100px 200px; /* 两行,高度分别为100px、200px */
}
3. grid-template-areas
grid-template-areas属性定义了Grid区域:
.container {
grid-template-areas:
"<区域名>...";
}
例如:
.container {
grid-template-areas:
"header header header"
"sidebar main main"
"footer footer footer";
}
4. grid-template
grid-template是grid-template-columns、grid-template-rows和grid-template-areas的简写:
.container {
grid-template: <grid-template-rows> / <grid-template-columns>;
}
例如:
.container {
grid-template: 100px 200px / 1fr 2fr 1fr;
}
5. column-gap/row-gap
column-gap和row-gap属性定义了列轨道和行轨道之间的间距:
.container {
column-gap: <间距大小>;
row-gap: <间距大小>;
}
例如:
.container {
column-gap: 20px; /* 列间距为20px */
row-gap: 10px; /* 行间距为10px */
}
6. gap
gap是column-gap和row-gap的简写:
.container {
gap: <row-gap> <column-gap>;
}
例如:
.container {
gap: 10px 20px; /* 行间距为10px,列间距为20px */
}
如果只提供一个值,则行间距和列间距都使用该值:
.container {
gap: 10px; /* 行间距和列间距都为10px */
}
7. justify-items
justify-items属性定义了项目在单元格内的水平对齐方式:
.container {
justify-items: start | end | center | stretch;
}
start:项目从单元格左侧对齐end:项目从单元格右侧对齐center:项目在单元格内水平居中对齐stretch(默认):项目拉伸以填充单元格的宽度
8. align-items
align-items属性定义了项目在单元格内的垂直对齐方式:
.container {
align-items: start | end | center | stretch;
}
start:项目从单元格顶部对齐end:项目从单元格底部对齐center:项目在单元格内垂直居中对齐stretch(默认):项目拉伸以填充单元格的高度
9. place-items
place-items是align-items和justify-items的简写:
.container {
place-items: <align-items> <justify-items>;
}
例如:
.container {
place-items: center start; /* 垂直居中,水平左对齐 */
}
如果只提供一个值,则align-items和justify-items都使用该值:
.container {
place-items: center; /* 水平垂直居中对齐 */
}
10. justify-content
justify-content属性定义了网格在容器内的水平对齐方式(当网格总宽度小于容器宽度时):
.container {
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
start(默认):网格从容器左侧对齐end:网格从容器右侧对齐center:网格在容器内水平居中对齐stretch:网格拉伸以填充容器的宽度space-around:每个网格两侧的间距相等space-between:网格之间的间距相等,两端对齐space-evenly:网格之间的间距和网格与容器边缘的间距都相等
11. align-content
align-content属性定义了网格在容器内的垂直对齐方式(当网格总高度小于容器高度时):
.container {
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
start(默认):网格从容器顶部对齐end:网格从容器底部对齐center:网格在容器内垂直居中对齐stretch:网格拉伸以填充容器的高度space-around:每个网格两侧的间距相等space-between:网格之间的间距相等,两端对齐space-evenly:网格之间的间距和网格与容器边缘的间距都相等
12. place-content
place-content是align-content和justify-content的简写:
.container {
place-content: <align-content> <justify-content>;
}
例如:
.container {
place-content: center start; /* 垂直居中,水平左对齐 */
}
如果只提供一个值,则align-content和justify-content都使用该值:
.container {
place-content: center; /* 水平垂直居中对齐 */
}
13. grid-auto-columns/grid-auto-rows
grid-auto-columns和grid-auto-rows属性定义了自动生成的轨道(隐式网格)的大小:
.container {
grid-auto-columns: <轨道大小>;
grid-auto-rows: <轨道大小>;
}
例如:
.container {
grid-auto-rows: 100px; /* 自动生成的行轨道高度为100px */
}
14. grid-auto-flow
grid-auto-flow属性定义了项目的放置顺序:
.container {
grid-auto-flow: row | column | row dense | column dense;
}
row(默认):按行放置项目column:按列放置项目row dense:按行放置项目,并填充空白单元格column dense:按列放置项目,并填充空白单元格
15. grid
grid是一个复合属性,可以同时设置多个Grid容器属性:
.container {
grid: <grid-template-rows> / <grid-template-columns>;
}
例如:
.container {
grid: 100px 200px / 1fr 2fr 1fr;
}
项目属性
1. grid-column-start/grid-column-end
grid-column-start和grid-column-end属性定义了项目在列方向上的起始和结束位置:
.item {
grid-column-start: <列线>;
grid-column-end: <列线>;
}
例如:
.item {
grid-column-start: 1; /* 从第1条列线开始 */
grid-column-end: 3; /* 到第3条列线结束 */
}
2. grid-row-start/grid-row-end
grid-row-start和grid-row-end属性定义了项目在行方向上的起始和结束位置:
.item {
grid-row-start: <行线>;
grid-row-end: <行线>;
}
例如:
.item {
grid-row-start: 1; /* 从第1条行线开始 */
grid-row-end: 2; /* 到第2条行线结束 */
}
3. grid-column/grid-row
grid-column和grid-row是grid-column-start/grid-column-end和grid-row-start/grid-row-end的简写:
.item {
grid-column: <grid-column-start> / <grid-column-end>;
grid-row: <grid-row-start> / <grid-row-end>;
}
例如:
.item {
grid-column: 1 / 3; /* 从第1条列线开始,到第3条列线结束 */
grid-row: 1 / 2; /* 从第1条行线开始,到第2条行线结束 */
}
4. grid-area
grid-area属性可以通过Grid区域名称或行/列线来定位项目:
.item {
grid-area: <区域名>;
/* 或 */
grid-area: <grid-row-start> / <grid-column-start> / <grid-row-end> / <grid-column-end>;
}
例如:
.item {
grid-area: header; /* 使用区域名称 */
}
.item {
grid-area: 1 / 1 / 2 / 3; /* 使用行/列线 */
}
5. justify-self
justify-self属性定义了单个项目在单元格内的水平对齐方式,覆盖容器的justify-items属性:
.item {
justify-self: start | end | center | stretch;
}
start:项目从单元格左侧对齐end:项目从单元格右侧对齐center:项目在单元格内水平居中对齐stretch(默认):项目拉伸以填充单元格的宽度
6. align-self
align-self属性定义了单个项目在单元格内的垂直对齐方式,覆盖容器的align-items属性:
.item {
align-self: start | end | center | stretch;
}
start:项目从单元格顶部对齐end:项目从单元格底部对齐center:项目在单元格内垂直居中对齐stretch(默认):项目拉伸以填充单元格的高度
7. place-self
place-self是align-self和justify-self的简写:
.item {
place-self: <align-self> <justify-self>;
}
例如:
.item {
place-self: center start; /* 垂直居中,水平左对齐 */
}
如果只提供一个值,则align-self和justify-self都使用该值:
.item {
place-self: center; /* 水平垂直居中对齐 */
}
应用场景
1. 基本网格布局
<div class="container" style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
</div>
2. 页面布局
<div class="page" style="display: grid; grid-template-areas:
'header header header'
'sidebar main main'
'footer footer footer';
grid-template-columns: 200px 1fr 1fr;
grid-template-rows: 100px 1fr 50px;
height: 100vh;
gap: 10px;">
<header style="grid-area: header; background-color: #333; color: white;">
头部
</header>
<aside style="grid-area: sidebar; background-color: #f0f0f0;">
侧边栏
</aside>
<main style="grid-area: main; background-color: white;">
主要内容
</main>
<footer style="grid-area: footer; background-color: #333; color: white;">
页脚
</footer>
</div>
3. 响应式网格
<div class="container" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px;">
<div class="item">项目1</div>
<div class="item">项目2</div>
<div class="item">项目3</div>
<div class="item">项目4</div>
<div class="item">项目5</div>
<div class="item">项目6</div>
<div class="item">项目7</div>
<div class="item">项目8</div>
</div>
4. 居中对齐
<div class="container" style="display: grid; place-items: center; height: 300px;">
<div class="item">水平垂直居中内容</div>
</div>
注意事项
-
二维布局:Grid布局是二维布局模型,同时对行和列进行布局,适用于复杂的布局需求。
-
浏览器兼容性:Grid布局在现代浏览器中支持良好,但在一些旧版本浏览器中支持有限,需要考虑降级方案。
-
性能影响:Grid布局通常比传统布局技术性能更好,但过多的嵌套Grid容器可能会影响性能。
-
与Flexbox的区别:Grid布局是二维的,而Flexbox是一维的。Grid布局适用于整体页面布局,而Flexbox适用于组件内部的布局。
-
响应式设计:Grid布局提供了强大的响应式设计能力,通过
repeat()、auto-fit、minmax()等函数可以轻松创建响应式网格。
浏览器兼容性
| 浏览器 | 版本 | 支持情况 |
|---|---|---|
| Chrome | 57+ | 完全支持 |
| Firefox | 52+ | 完全支持 |
| Safari | 10.1+ | 完全支持 |
| Edge | 16+ | 完全支持 |
| IE | 不支持 | 不支持 |
总结
Grid布局是一种强大的二维布局模型,它使得创建复杂的二维布局变得更加容易。通过容器属性和项目属性的组合,可以实现各种复杂的布局效果。Grid布局特别适用于整体页面布局、复杂的卡片布局、响应式设计等场景。在现代Web开发中,Grid布局已经成为布局的首选技术之一,与Flexbox一起构成了现代CSS布局的核心。