一、概述
目前,CSS 网格布局(Grid)是当之无愧的最强 CSS 布局方案。
它的核心能力是将网页拆解为整齐的网格,只要灵活组合这些网格,就能轻松实现各种复杂布局。要知道,这类布局在以前,必须借助复杂的 CSS 框架才能做到,而现在浏览器已经原生支持了。

如上图所示的布局,恰好是 Grid 布局的专长领域。Grid 布局与 Flex 布局存在共通之处:二者均具备对容器内多个项目位置的精准控制能力。但其本质区别在于:Flex 布局以轴线为核心机制,仅支持沿主轴或交叉轴对项目进行定位,属于一维布局模式;而 Grid 布局的实现逻辑是先将容器分割为清晰的 “行” 与 “列”,形成独立的单元格结构,再通过指定项目所属单元格完成定位,属于二维布局模式。就布局能力而言,Grid 布局在灵活性与功能性上均远优于 Flex 布局。
二、基本概念
2.1 容器和项目
当一个区域采用网格布局时,该区域可称为 “容器”(container);而容器内部那些以网格方式定位的直接子元素,被称作 “项目”(item)。
<div>
<span><p>1</p></span>
<span><p>2</p></span>
</div>
来看这段代码:最外层的<div>是容器,里面的两个<span>是项目。这里要特别注意一个规则:项目只能是容器的直接子元素,项目自己的子元素(像代码里的<p>)不算项目。而且,Grid 布局只对项目生效,对其他元素不产生影响
三、容器属性
我们可以把 Grid 布局的属性分成两类:一类是加在容器上的,叫做容器属性;另一类是加在项目上的,叫做项目属性。这一节,我们先从容器属性开始学习。
3.1 display 属性
当我们为容器定义 display: grid 时,该容器便会启用网格布局模式。
div {
display: grid;
}

上图为display: grid的布局效果。
需要注意的是,容器默认是块级元素,但这并非固定不变,我们也能根据布局需求,把它设置成行内元素。
div {
display: inline-grid;
}
大家可以看到,上面这段代码做了两件事:一是把这个<div>设为行内元素,二是让这个元素的内部使用网格布局。

上图为display: inline-grid的布局效果。
这里有个关键知识点必须记住:当容器采用网格布局后,项目上之前设置的一些样式会失效。
比如控制浮动的 float,控制显示方式的
display: inline-block 和 display: table-cell,
控制垂直对齐的 vertical-align,还有用于多列布局的
column-* 相关属性,全都不再起作用。
3.2、grid-template-columns 属性,grid-template-rows 属性
记住这个关键步骤:容器设置好网格布局后,就要开始划分行和列了。我们用 grid-template-columns 属性来规定每一列有多宽,用 grid-template-rows 属性来规定每一行有多高,这两个属性是构建网格结构的基础。
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
}
上述代码中,网格布局被配置为三行三列的结构,其列宽属性(grid-template-columns)与行高属性(grid-template-rows)的取值均为 100px,即网格的列宽与行高统一为 100px。

网格布局中,行列尺寸的定义支持多种单位类型。除绝对单位外,百分比单位也是常用的尺寸定义方式之一。
.container {
display: grid;
grid-template-columns: 33.33% 33.33% 33.33%;
grid-template-rows: 33.33% 33.33% 33.33%;
}
(1)repeat()
当行列尺寸存在大量重复值时,直接重复书写会降低代码效率。在此情况下,可通过 repeat() 函数对重复值进行简化定义。上述代码基于 repeat() 函数的改写结果如下。
.container {
display: grid;
grid-template-columns: repeat(3, 33.33%);
grid-template-rows: repeat(3, 33.33%);
}
repeat() 函数的参数构成明确:第一个参数用于设定重复的次数(如示例中的 3),第二个参数用于指定需重复的目标值。
需要注意的是,repeat() 函数不只能重复单个值,就算是一种组合模式,它也能照样重复。比如像 “宽 20px + 宽 30px” 这样的模式,也可以用 repeat() 来重复。
grid-template-columns: repeat(2, 100px 20px 80px);
大家看这段代码,它定义了 6 列,每列的宽度对应关系很清晰:
- 第 1 列和第 4 列:100px
- 第 2 列和第 5 列:20px
- 第 3 列和第 6 列:80px这种分布其实是 “100px 20px 80px” 模式重复了 2 次的结果。

(2)auto-fill 关键字
大家可以想象这样一种情况:单元格大小是固定的,但容器有多大我们不确定。这时候如果想让每行(或每列)能塞下多少单元格就塞多少,怎么办呢?用 auto-fill 关键字就可以了,它能自动帮我们填充最多的单元格。
.container {
display: grid;
grid-template-columns: repeat(auto-fill, 100px);
}
上述代码中,列宽参数被设定为 100px,配合自动填充逻辑,会使网格在容器空间内持续填充 100px 宽的列,直至容器剩余空间小于单列宽度(100px)时停止。

auto-fit 与 auto-fill 功能相近,核心行为一致。差异仅出现于以下场景:容器宽度足以容纳全部单元格,且单元格宽度为非固定值。此时,auto-fill 的表现为以空白单元格填充剩余空间;auto-fit 的表现为通过扩展单元格宽度消耗剩余空间。
(3)fr 关键字
fr 关键字(源自 “fraction”,意为 “片段”)是网格布局中用于表达比例关系的专用单位。例如,当两列的宽度属性分别为 1fr 和 2fr 时,二者的宽度比例为 1:2,即后者的宽度为前者的两倍。
.container {
display: grid;
grid-template-columns: 1fr 1fr;
}
上述代码中,网格的列数为 2,且两列的宽度属性被配置为等值,即两列宽度相同。

fr 单位支持与绝对长度单位联合使用,这种混合模式可高效处理 “固定尺寸 + 比例分配” 的布局场景,显著提升配置便捷性。
.container {
display: grid;
grid-template-columns: 150px 1fr 2fr;
}
上述代码中,列宽配置为:第一列宽度值为 150px(绝对长度),第二列与第三列的宽度比例为 1:2(即第二列宽度为第三列的 1/2)。

(4)minmax()
可以把 minmax() 函数理解为 “设定长度的上下限”。它需要两个值:一个是最小值,一个是最大值。比如 minmax(100px, 200px) 就表示长度不能小于 100px,也不能大于 200px,会在这个范围内根据情况调整。
grid-template-columns: 1fr 1fr minmax(100px, 1fr);
大家可以这样理解这段代码里的 minmax(100px, 1fr):这列的宽度有两个限制 —— 最小不能小于 100px,最大不能超过 1fr。也就是说,不管容器怎么变,这列再窄不会窄于 100px,也不会宽过 1fr 所分配的空间。
(5)auto 关键字
auto 作为网格布局中的长度关键字,其作用是将长度的计算权交由浏览器,由浏览器根据上下文(如内容大小、容器空间等)自动决定最终长度。
grid-template-columns: 100px auto 100px;
上述代码中,第二列的宽度计算规则为:默认等于该列所有单元格的最大宽度;当单元格内容的 min-width 属性值存在且大于上述最大宽度时,列宽将被 min-width 值覆盖。
(6)布局实例
grid-template-columns 是网页布局的高效工具,对于两栏式布局,通过单行代码即可快速实现(例如 grid-template-columns: 200px 1fr;)。
.wrapper {
display: grid;
grid-template-columns: 70% 30%;
}
在上述代码示例里,通过 grid-template-columns 属性将两栏布局的宽度比例配置为 70% 与 30%,即左栏占 70%,右栏占 30%。
对于传统的十二网格布局,通过 grid-template-columns 等属性可简化实现过程,例如使用 repeat(12, 1fr) 即可快速定义 12 列等宽网格,编写起来十分便捷。
grid-template-columns: repeat(12, 1fr);
3.3、grid-row-gap 属性,grid-column-gap 属性,grid-gap 属性
grid-row-gap 属性的作用是指定网格布局中行与行的间隔距离(行间距),grid-column-gap 属性的作用是指定列与列的间隔距离(列间距),二者共同控制网格内部的间距分布。
.container {
grid-row-gap: 20px;
grid-column-gap: 20px;
}

为了简化代码,我们可以用 grid-gap 同时设置列间距和行间距,它是 grid-column-gap 和 grid-row-gap 的简写形式。具体怎么写呢?语法如下:
grid-gap: <grid-row-gap> <grid-column-gap>;
.container {
grid-gap: 20px 20px;
}
grid-gap 的简写语法中,当仅传入一个值时,浏览器会将该值同时应用于 grid-row-gap 和 grid-column-gap,即第二个值默认与第一个值相同。
最新标准对网格间距属性名称进行了简化,具体调整如下:
- 原
grid-column-gap→ 现column-gap - 原
grid-row-gap→ 现row-gap - 原
grid-gap→ 现gap即三个属性均已移除grid-前缀。
3.4 grid-auto-flow 属性
网格布局划分完成后,容器的子元素将按照预设的默认顺序自动填充至网格单元。默认填充顺序为 “先行后列”,即优先填充当前行的所有列,待该行填充完毕后,再启动下一行的填充流程,其排列顺序与下图中数字标识的顺序相符。

grid-auto-flow 属性定义了网格子元素的自动布局顺序:其初始值为 row,表示采用 “先行后列” 的排列逻辑(沿行方向优先填充);当属性值设为 column 时,排列逻辑切换为 “先列后行”(沿列方向优先填充)。
grid-auto-flow: column;
在上述代码中,当 grid-auto-flow 被设置为 column 时,网格子元素的自动排列顺序切换为 “先列后行”,具体顺序如以下图示。

grid-auto-flow 的可选值还包括 row dense 和 column dense。它们的核心功能是在布局中存在指定位置的项目时,优化剩余项目的自动放置逻辑 —— 通过 “紧凑填充” 的方式减少空白区域,使布局更密集。
在以下示例中,1 号与 2 号项目均被设置为占据两个单元格;由于 grid-auto-flow 默认为 row(先行后列),剩余项目将按此规则填充,最终布局效果如下。

图中 1 号项目后的空位源于默认布局逻辑:3 号项目会接续 2 号项目的位置排列。当grid-auto-flow设为row dense时,布局规则调整为 “先行后列” 且启用密集填充模式,剩余项目将优先填补空白区域,尽可能避免空格。
grid-auto-flow: row dense;
上面代码的效果如下。

上图会先填满第一行,再填满第二行,所以3号项目就会紧跟在1号项目的后面。8号项目和9号项目就会排到第四行。
如果将设置改为column dense,表示”先列后行”,并且尽量填满空格。
grid-auto-flow: column dense;

上图呈现的是 “先列后行” 的填充逻辑,布局时会优先填满一列再推进至下一列。基于此规则,3 号项目落入第一列,4 号项目进入第二列,受前面项目排列影响,8 号与 9 号项目被挤压到第四列。
3.5、justify-items 属性,align-items 属性,place-items 属性
justify-items 和 align-items 是网格布局中控制单元格内容对齐的核心属性:前者针对水平方向,定义内容在单元格内的左右位置(如左对齐、居中、右对齐);后者针对垂直方向,定义内容在单元格内的上下位置(如顶部对齐、居中、底部对齐)。
.container {
justify-items: start | end | center | stretch;
align-items: start | end | center | stretch;
}
justify-items 与 align-items 具有一致的语法结构,二者可使用的属性值完全相同,具体取值如下。
- start:对齐单元格的起始边缘。
- end:对齐单元格的结束边缘。
- center:单元格内部居中。
- stretch:拉伸,占满单元格的整个宽度(默认值)。
.container {
justify-items: start;
}
上述代码设置单元格内容为左对齐,对应的效果如下图所示。

.container {
align-items: start;
}
上述代码设置单元格内容为头部对齐,对应的效果如下图所示。

place-items 属性用于合并声明 align-items 和 justify-items,是二者的简写形式,可一次性配置单元格内容的垂直对齐与水平对齐规则。
place-items: <align-items> <justify-items>;
place-items: start end;
place-items 的简写语法中,当仅指定一个值时,浏览器会将该值同时应用于 align-items 和 justify-items,即省略的第二个值默认与第一个值一致。
3.6、justify-content 属性,align-content 属性,place-content 属性
对于网格布局的容器而言,justify-content 控制的是整个内容区域在容器中的水平对齐位置(左、中、右),align-content 控制的是同一内容区域在容器中的垂直对齐位置(上、中、下)。
关键区别:与 justify-items/align-items 的对比
二者极易与控制单元格内容对齐的属性混淆,核心差异如下:
| 属性 | 作用对象 | 生效条件 | 控制方向 |
|---|---|---|---|
justify-content | 整个网格内容区域 | 网格总宽度 < 容器宽度 | 水平方向(左 / 中 / 右) |
align-content | 整个网格内容区域 | 网格总高度 < 容器高度 | 垂直方向(上 / 中 / 下) |
justify-items | 单个单元格内的内容 | 单元格宽度 > 内容宽度 | 水平方向 |
align-items | 单个单元格内的内容 | 单元格高度 > 内容高度 | 垂直方向 |
.container {
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
justify-content 和 align-content 不仅功能逻辑对应(分别控制水平 / 垂直对齐),语法规则与可取值也完全相同,具体取值如下。需注意,下方示例图以 justify-content 为演示对象,align-content 的效果图示仅方向不同 —— 将水平对齐效果转换为垂直对齐即可
- start – 对齐容器的起始边框。

- end – 对齐容器的结束边框。

- center – 容器内部居中。

- stretch – 项目大小没有指定时,拉伸占据整个网格容器。

- space-around – 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍。

- space-between – 项目与项目的间隔相等,项目与容器边框之间没有间隔。

- space-evenly – 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔。

place-content 作为网格容器级对齐的简写属性,整合了 align-content(控制内容区域垂直位置)和 justify-content(控制内容区域水平位置)的功能,通过单条声明即可同时定义两者的属性值。
place-content: <align-content> <justify-content>
在 place-content 的简写规则中,若省略第二个参数,用户代理(浏览器)将默认第二个参数的值等于第一个参数的值,即内容区域的垂直对齐方式与水平对齐方式取相同值。
3.7、grid-auto-columns 属性,grid-auto-rows 属性
grid-auto-columns 属性的功能是指定浏览器自动创建的额外列网格的宽度,grid-auto-rows 属性的功能是指定自动创建的额外行网格的高度。二者与 grid-template-columns、grid-template-rows 具有完全一致的语法结构;若未对其进行声明,用户代理(浏览器)将根据对应网格内单元格内容的尺寸,确定新增网格的列宽和行高。
在以下示例里,通过网格属性将容器划分为 3 行 ×3 列的显式网格。然而,布局中 8 号项目的位置被指定为第 4 行,9 号项目的位置被指定为第 5 行,超出了预设的网格行数。
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
grid-auto-rows: 50px;
}
上述代码中,显式定义的原始网格行高为 100px,同时通过配置指定,浏览器自动创建的新增行网格高度统一为 50px,实现了原始行与新增行的高度差异化设置。

3.8、grid-template 属性,grid 属性
grid-template 属性为合并声明属性,其涵盖范围包括 grid-template-columns、grid-template-rows 与 grid-template-areas。grid 属性作为更为全面的合并简写属性,涵盖 grid-template-rows、grid-template-columns、grid-template-areas、grid-auto-rows、grid-auto-columns 及 grid-auto-flow 六项属性。基于前述基础属性已完成讲解,此处不对这两个简写属性进行详细阐述。
四、项目属性
4.1、grid-column-start 属性,grid-column-end 属性,grid-row-start 属性,grid-row-end 属性
指定网格项目位置的核心方法,是为项目的四个边框(上、下、左、右)分别设定对应的网格线,通过边框与网格线的绑定关系,精准确定项目在网格中的位置。
- grid-column-start属性:左边框所在的垂直网格线
- grid-column-end属性:右边框所在的垂直网格线
- grid-row-start属性:上边框所在的水平网格线
- grid-row-end属性:下边框所在的水平网格线
.item-1 {
grid-column-start: 2;
grid-column-end: 4;
}
这段代码对 1 号项目的水平位置做了限定:左边框对齐第二根垂直网格线,右边框对齐第四根垂直网格线,这意味着项目会横跨这两根网格线之间的区域。

图示中,1 号项目的水平方向边框(左右)已明确指定网格线,垂直方向边框(上下)未做声明。依据默认布局规则,其垂直方向边框将采用初始定位:上边界与第一根水平网格线重合,下边界与第二根水平网格线重合。
1 号项目为手动定位,其余项目依赖浏览器自动布局,其排列顺序由grid-auto-flow属性控制:默认row对应 “先行后列”。若要探索不同布局效果,可将属性值分别改为column(先列后行)、row dense(行方向消除空位)、column dense(列方向消除空位),对比其他项目的位置差异。
下面代码针对1号项目指定四个边框线效果。
.item-1 {
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 2;
grid-row-end: 4;
}

大家可以这样理解:这四个控制边框的属性,除了直接写网格线编号,还能用span加数字,意思是 “跨几个格子”。比如想让项目左右边框之间跨 2 个网格,就可以写span 2;上下边框之间跨 3 个网格,也用span 3,这样就不用算具体是哪根网格线了。
.item-1 {
grid-column-start: span 2;
}
这段代码通过相关属性(如grid-column: span 2)明确,1 号项目的左边框与右边框之间横向跨越 2 个网格,对应水平方向占据 2 个网格的空间。

这与下面的代码效果完全一样。
.item-1 {
grid-column-end: span 2;
}
若通过这四个属性定位项目时出现重叠现象,解决显示顺序的方案是使用z-index属性:为重叠项目分别设置不同的z-index值,值较高的项目将覆盖值较低的项目,以此控制重叠时的可见层级。
4.2、grid-column 属性,grid-row 属性
grid-column 是 grid-column-start 与 grid-column-end 的简写,格式通常为 起始线 / 结束线(如 2 / 4);grid-row 是 grid-row-start 与 grid-row-end 的简写,格式一致,通过单条声明即可完成项目水平或垂直方向的定位。
.item {
grid-column: <start-line> / <end-line>;
grid-row: <start-line> / <end-line>;
}
.item-1 {
grid-column: 1 / 3;
grid-row: 1 / 2;}
/* 等同于 */
.item-1 {
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 2;
}
在上述代码里,项目 item-1 的行位置被限定在第一行,列方向上通过网格线定位 —— 左侧对齐第一根垂直列线,右侧对齐第三根垂直列线,即横向跨越从第 1 列到第 2 列的区域。
grid-column和grid-row中使用span关键字的示例:grid-column: 2 / span 3表示从第 2 根列线开始向右跨 3 个网格;grid-row: span 2表示从当前行线开始向下跨 2 个网格,简化了定位写法。
.item-1 {
background: #b03532;
grid-column: 1 / 3;
grid-row: 1 / 3;
}
/* 等同于 */
.item-1 {
background: #b03532;
grid-column: 1 / span 2;
grid-row: 1 / span 2;
}
在上述代码里,项目 item-1 的布局范围明确:行方向覆盖第一行和第二行,列方向覆盖第一列和第二列,整体占据一个 2 行 2 列的网格区域。

若省略斜杠及后面的部分,默认表示跨越一个网格。
.item-1 {
grid-column: 1;
grid-row: 1;
}
上述代码中,项目 item-1 位于左上角的第一个网格。
4.3、justify-self 属性,align-self 属性,place-self 属性
justify-self 属性用于指定单个网格项目的内容在其单元格内的水平对齐方式(左、中、右),其语法规则与 justify-items 完全一致,但应用范围限定为单个项目;align-self 属性用于指定单个网格项目的内容在其单元格内的垂直对齐方式(上、中、下),其语法规则与 align-items 完全一致,应用范围同样限定为单个项目。
.item {
justify-self: start | end | center | stretch;
align-self: start | end | center | stretch;
}
justify-self 和 align-self 均可取以下四个值:
- start:对齐单元格的起始边缘;
- end:对齐单元格的结束边缘;
- center:在单元格内部居中;
- stretch:拉伸并占满单元格的整个宽度(默认值)。
.item-1 {
justify-self: start;
}

place-self 的语法通常为 “垂直值 水平值”(如 place-self: center end 对应 align-self: center; justify-self: end),若只写一个值,则同时应用于垂直和水平方向,简化了单个项目的对齐设置。
place-self: <align-self> <justify-self>;
place-self: center center;
如果省略第二个值,place-self属性会认为这两个值相等。
至此,Grid 布局的常用属性已基本介绍完毕。掌握这些内容,足以应对工作中的大部分布局需求。
作为当前主流的布局方案,Grid 与 Flex 布局在众多前端框架(如 Bootstrap、Tailwind CSS、Element UI)中均有广泛且重要的应用。因此,对于 Web 开发人员而言,熟练掌握二者是十分必要的。
此外,传统布局方式(通过 display、position、float 组合实现)虽操作相对繁琐,但它是所有 CSS 布局的基础,同样需要扎实掌握,不可忽视。
虽然Grid属性较多但是只要掌握常用的几个足以慢慢上手
在文章的最后,我会给出开篇第一张图(即文章封面图)的布局代码作为示例,如下所示:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>戎码生涯-Grid布局</title>
<style >
.container {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-auto-rows: 40px;
gap: 5px;
}
.container>span:nth-child(1) {
grid-column-start: span 2;
grid-row-start: span 2;
}
.container>span:nth-child(3) {
grid-row-start: span 2;
}
.container>span {
display: grid;
place-items: center;
border-radius: 10px;
background: rgb(195, 93, 199);
}
</style>
</head>
<body>
<span class="container">
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
</span>
</body>
</html>









