Grid网格布局
前言
一样的,在学习之前,搞懂一些匪夷所思的概念:
单元格和项目,学习之初,视频教程都会拿出一张无数常规的网格图片讲网格布局,这当然没问题,但是如果讲到单元格和项目,这时候就懵了,因为教程说的它们是不一样的,但是图片里面表现又一样,其实就是一个先入为主了,因为网格布局最常用的反而不像图片那样一张网格,而是会跨列跨行,所以可以理解单元格是一种虚无的东西,无形的大网,而项目是实实在在的东西,如果它们刚好落在每个单元格,那确实会像单元格=项目,而一般情况下,项目是会跨 单元格的
网格线、轨道和间距也是一个比较难理解的地方:
Grid 基础知识
CSS Grid(网格布局)是一种二维布局系统,能够同时控制元素在行(Row)和列(Column)两个方向上的排列。
使用 Grid 布局时,浏览器会建立一套网格结构,再根据布局规则将 HTML 元素放置到网格中。
Grid 容器和项目
Grid 布局主要包含两个基本对象:
- Grid 容器(Container):设置了
display: grid或display: inline-grid的元素。 - Grid 项目(Item):Grid 容器中参与网格布局的直接子元素。
<div class="container"> <div class="item">项目1</div> <div class="item">项目2</div> <div class="item">项目3</div></div>.container { display: grid; grid-template-columns: repeat(3, 100px); gap: 10px;}此时 .container 是 Grid 容器,三个 .item 是 Grid 项目,按照网格布局规则排列。
常见的容器属性和项目属性:
| 容器属性 | 项目属性 |
|---|---|
grid-template-columns | grid-column |
grid-template-rows | grid-row |
grid-template-areas | grid-area |
gap | justify-self |
justify-items | align-self |
align-items | order |
注意:容器负责定义和管理网格结构,项目则根据网格规则进行排列。
行、列和单元格
Grid 会将布局空间划分为行(Row)和列(Column),两者交叉形成单元格(Cell)。
- 行(Row):网格中水平方向的一排空间。
- 列(Column):网格中垂直方向的一列空间。
- 单元格(Cell):一行与一列交叉形成的最小网格空间。
例如,创建一个 2 行 3 列的网格:
.container { display: grid; grid-template-columns: 100px 200px 100px; grid-template-rows: 80px 120px;}这段代码定义了:
- 3 列:宽度分别为
100px、200px、100px。 - 2 行:高度分别为
80px、120px。 - 6 个单元格:每行 3 个,共 2 行。
单元格的尺寸由所在行、列的尺寸共同决定:
| 单元格位置 | 宽度 | 高度 |
|---|---|---|
| 第一行第一列 | 100px | 80px |
| 第一行第二列 | 200px | 80px |
| 第一行第三列 | 100px | 80px |
| 第二行第一列 | 100px | 120px |
| 第二行第二列 | 200px | 120px |
| 第二行第三列 | 100px | 120px |
单元格与项目的区别
这是 Grid 布局中非常容易混淆的概念。
单元格是浏览器划分的布局空间,项目是实际参与布局的 HTML 元素。
它们之间并不一定是一一对应的关系。
情况一:一个项目占据一个单元格。
这是最常见的情况,项目默认自动排列,通常一个项目占据一个单元格。
情况二:一个项目占据多个单元格。
.item { grid-column: 1 / 3; grid-row: 1 / 3;}项目横跨 2 行、2 列,占据 4 个单元格。
需要注意,跨行、跨列不会真正合并单元格,只是让项目占据更大的网格区域。
情况三:存在没有项目的单元格。
即使没有对应的 HTML 元素,已经建立的网格中仍然可以存在空单元格。
因此,单元格和项目不能画等号。
网格线
网格线(Grid Line)是用于划分网格和定位项目的参考线。
网格线分为两种:
- 列网格线:垂直方向的参考线,用于划分列。
- 行网格线:水平方向的参考线,用于划分行。
例如:
.container { display: grid; grid-template-columns: repeat(3, 100px); grid-template-rows: repeat(2, 80px);}这会形成:
| 网格结构 | 数量 |
|---|---|
| 行 | 2 |
| 列 | 3 |
| 行网格线 | 3 |
| 列网格线 | 4 |
| 单元格 | 6 |
在普通的显式网格中,某一方向的网格线数量 = 对应方向的轨道数量 + 1。
网格线的作用
网格线最主要的用途是确定项目的起始位置和结束位置,从而实现跨行、跨列布局。
例如:
.item { grid-column: 1 / 3; grid-row: 1 / 3;}grid-column: 1 / 3:从第 1 条列网格线到第 3 条列网格线,横跨 2 列。grid-row: 1 / 3:从第 1 条行网格线到第 3 条行网格线,纵跨 2 行。
也可以使用 span 表示跨越的轨道数量:
.item { grid-column: span 2; grid-row: span 2;}两种方式的区别:
1 / 3:指定起始和结束网格线。span 2:指定跨越 2 条轨道,起始位置可以由自动布局确定。
网格线能不能自定义?
可以为网格线命名:
.container { display: grid; grid-template-columns: [start] 100px [middle] 200px [end];}
.item { grid-column: start / end;}不过网格线属于抽象的布局参考线,并不是真正显示出来的 CSS 边框,不能直接像 border 一样设置颜色和线条样式。
其他(间距、区域、内容、轨道)
1. 间距(Gap)
间距用于控制相邻行轨道、列轨道之间的距离。
常见属性:
| 属性 | 说明 |
|---|---|
row-gap | 行轨道之间的间距 |
column-gap | 列轨道之间的间距 |
gap | 两者的简写 |
.container { display: grid; grid-template-columns: 100px 200px; grid-template-rows: 80px 120px; gap: 10px 20px;}这里:
- 行间距:
10px。 - 列间距:
20px。
间距到底占不占单元格的空间?
间距不属于单元格,也不计入普通轨道自身的尺寸。
但是,间距会占据整个网格中的空间。
例如:
.container { display: grid; grid-template-columns: 100px 200px; column-gap: 20px;}显式网格的总宽度为:
100px + 20px + 200px = 320px其中 20px 是额外的轨道间距,两个列轨道仍然分别宽 100px 和 200px。
如果使用 1fr 等弹性轨道,在空间受限时,浏览器会先考虑间距,再将剩余可分配空间分给弹性轨道。
间距与网格线的关系
CSS Grid 规范中,可以将 gap 形象地理解为网格线具有了厚度。
但要注意:
- 这只是布局计算层面的理解。
- 不意味着网格线真的变成了可见的粗线。
- 也不能认为网格线等于轨道宽度加间距。
2. 区域(Area)
网格区域(Grid Area)是由四条网格线限定的矩形空间,可以包含一个或多个单元格。
可以通过 grid-template-areas 为区域命名:
<div class="container"> <header class="header">头部</header> <main class="main">主体</main> <aside class="aside">侧边栏</aside></div>.container { display: grid; grid-template-columns: 100px 200px 100px; grid-template-rows: 80px 120px; gap: 10px;
grid-template-areas: "header header aside" "main main aside";}
.header { grid-area: header;}
.main { grid-area: main;}
.aside { grid-area: aside;}这里虽然只有三个项目,但实际上建立了 2 行 3 列,共 6 个单元格。
header:占据第一行的前两个单元格。main:占据第二行的前两个单元格。aside:占据第三列的两个单元格。
注意:
区域并不一定要通过 **grid-template-areas** 命名。
通过 grid-column 和 grid-row 指定的矩形范围,同样是网格区域。
单元格可以理解为最小的网格区域,而更大的区域则可以包含多个单元格及它们之间的间距。
3. 内容(Content)
内容通常指项目内部的文字、图片、按钮等实际内容,而不是另一种网格结构。
例如:
<div class="container"> <div class="item"> <h3>文章标题</h3> <p>文章内容</p> </div></div>这里:
.container:Grid 容器。.item:Grid 项目。h3和p:项目内部的内容元素。
内容会影响元素自身的尺寸,并可能影响使用 auto 等尺寸规则的轨道。
Grid 还提供了对齐相关属性:
| 属性 | 说明 |
|---|---|
justify-items | 控制项目在其网格区域内的行内方向对齐 |
align-items | 控制项目在其网格区域内的块级方向对齐 |
justify-content | 控制整个网格轨道集合在容器内的行内方向对齐或分布 |
align-content | 控制整个网格轨道集合在容器内的块级方向对齐或分布 |
常见的水平书写模式下,行内方向通常是水平,块级方向通常是垂直。
需要区分:项目的对齐与项目内部文字的对齐不是同一回事。
4. 轨道(Track)
轨道是 Grid 布局中用于定义行、列空间尺寸的概念。
轨道分为两种:
- 列轨道(Column Track):两条相邻列网格线之间的列空间,其宽度决定这一列单元格的宽度。
- 行轨道(Row Track):两条相邻行网格线之间的行空间,其高度决定这一行单元格的高度。
例如:
.container { display: grid; grid-template-columns: 100px 200px 100px; grid-template-rows: 80px 120px;}这里建立了:
- 3 条列轨道。
- 2 条行轨道。
- 6 个单元格。
轨道与单元格有什么区别?
可以借助 Excel 来理解:
- 轨道类似 Excel 中的一整行或一整列。
- 单元格类似 Excel 中行与列交叉形成的格子。
不过轨道并不是将单元格的宽度或高度累加起来得到的。
例如第一列宽 100px,那么该列每个单元格都宽 100px,而不是整列所有单元格宽度加起来为 100px。
轨道与间距有什么关系?
轨道是相邻、平行网格线之间的带状空间,不能把它理解成一节一节的独立盒子。
列轨道纵向延伸时会经过行间距,行轨道横向延伸时也会经过列间距。
但:
- 列轨道的宽度不包含
column-gap。 - 行轨道的高度不包含
row-gap。
因此,虽然间距会影响整个网格的尺寸,但不会直接计入普通轨道自身的宽度或高度。
总结
| 概念 | 通俗理解 | 主要作用 |
|---|---|---|
| 容器(Container) | 网格布局的外层元素 | 建立网格布局 |
| 项目(Item) | 放入网格中的 HTML 元素 | 参与排列、定位和跨行跨列 |
| 行(Row) | 横向的一排 | 组织网格结构 |
| 列(Column) | 纵向的一列 | 组织网格结构 |
| 单元格(Cell) | 最小的格子 | 提供基本网格空间 |
| 网格线(Line) | 看不见的定位参考线 | 划分轨道、定位项目 |
| 轨道(Track) | 一条行或列空间 | 定义行高、列宽 |
| 间距(Gap) | 相邻轨道之间的空隙 | 分隔行与列 |
| 区域(Area) | 一个或多个单元格构成的矩形空间 | 表示项目可以占据的范围 |
| 内容(Content) | 项目内部的文字、图片等 | 组成实际页面内容 |
最需要记住的三个区别:
- 单元格 ≠ 项目:单元格是布局空间,项目是实际元素。
- 轨道 ≠ 间距:轨道定义行高、列宽,间距是相邻轨道之间额外的空间。
- 网格线 ≠ 轨道:网格线是参考边界,轨道是相邻网格线之间的空间。
最后,可以把 Grid 的整个工作过程概括为:
容器建立网格 → 轨道定义行列尺寸 → 行列交叉形成单元格 → 网格线用于定位 → 项目占据对应的网格区域。
gap 负责相邻轨道之间的留白,而项目内部的内容最终构成我们看到的页面。
理解这些概念后,再学习 Grid 容器属性、项目属性以及实际布局,就会清晰很多。
Grid 容器的属性
Grid 容器属性主要用于定义网格的行列结构、轨道尺寸、排列方向、间距以及项目的对齐方式。
一、display
通过 display 属性创建 Grid 容器,使其直接子元素按照网格布局规则排列。
| 属性值 | 说明 |
|---|---|
grid | 创建块级 Grid 容器 |
inline-grid | 创建行内级 Grid 容器 |
.container { display: grid;}两者的区别:
display: grid:容器在外部表现为块级元素,内部使用 Grid 布局。display: inline-grid:容器在外部表现为行内级元素,内部同样使用 Grid 布局。
注意:设置 display: grid 后,即使没有定义行列,浏览器也会根据布局规则自动创建网格轨道。
二、grid-template-rows / grid-template-columns
这两个属性用于定义 Grid 显式网格的行列轨道及其尺寸。
| 属性 | 说明 |
|---|---|
grid-template-columns | 定义列轨道及其宽度 |
grid-template-rows | 定义行轨道及其高度 |
1. 基本使用
.container { display: grid; grid-template-columns: 100px 200px 100px; grid-template-rows: 80px 120px;}表示:
- 3 条列轨道:宽度分别为
100px、200px、100px。 - 2 条行轨道:高度分别为
80px、120px。 - 两者交叉形成 6 个单元格。
注意:定义了 6 个单元格,不代表必须有 6 个项目。 即使只有两个 HTML 子元素,这套网格结构仍然存在。
2. 常用属性值
| 属性值 | 说明 |
|---|---|
100px | 固定轨道尺寸 |
50% | 相对于 Grid 容器对应的尺寸计算百分比 |
auto | 根据可用空间、内容等规则确定尺寸 |
1fr | 使用一份弹性空间 |
repeat() | 重复定义轨道 |
minmax() | 指定轨道尺寸范围 |
fr 单位
fr 表示分配给弹性轨道的空间份额。
.container { display: grid; grid-template-columns: 1fr 2fr 1fr;}在空间充足且没有额外尺寸限制的情况下,三列按照 1:2:1 分配可用空间。
repeat() 函数
用于简化重复的轨道定义。
.container { display: grid; grid-template-columns: repeat(3, 100px);}等价于:
grid-template-columns: 100px 100px 100px;minmax() 函数
用于设置轨道尺寸的最小值和最大值。
.container { display: grid; grid-template-columns: repeat(3, minmax(100px, 1fr));}每列最小宽度为 100px,空间充足时可以弹性扩展。
需要注意,最小尺寸限制可能导致网格在容器较窄时溢出。
三、grid-auto-flow
grid-auto-flow 用于控制没有明确指定位置的 Grid 项目如何自动排列。
| 属性值 | 说明 |
|---|---|
row | 默认值,优先沿行方向依次排列 |
column | 优先沿列方向依次排列 |
row dense | 按行排列,并尝试用后续项目填补空位 |
column dense | 按列排列,并尝试用后续项目填补空位 |
1. row(默认)
.container { display: grid; grid-template-columns: repeat(3, 100px); grid-auto-flow: row;}假设有 6 个项目:
┌───┬───┬───┐│ 1 │ 2 │ 3 │├───┼───┼───┤│ 4 │ 5 │ 6 │└───┴───┴───┘项目优先从左到右排列,当前行无法继续放置时,自动进入下一行。
2. column
.container { display: grid; grid-template-rows: repeat(3, 80px); grid-auto-flow: column; grid-auto-columns: 100px;}假设有 6 个项目:
┌───┬───┐│ 1 │ 4 │├───┼───┤│ 2 │ 5 │├───┼───┤│ 3 │ 6 │└───┴───┘项目优先沿列方向排列,当前列无法继续放置时,自动进入下一列。
3. dense
.container { display: grid; grid-template-columns: repeat(3, 100px); grid-auto-flow: row dense;}当某些项目跨越多列而产生空位时,dense 会尝试使用后续能够放入空位的项目进行填补。
注意:dense 可能导致项目的视觉排列顺序与 HTML 源码顺序不同,因此需要考虑键盘导航和阅读顺序。
四、grid-auto-rows / grid-auto-columns
这两个属性用于控制隐式网格轨道(Implicit Tracks)的尺寸。
| 属性 | 说明 |
|---|---|
grid-auto-rows | 设置自动创建的隐式行轨道尺寸 |
grid-auto-columns | 设置自动创建的隐式列轨道尺寸 |
1. 显式网格和隐式网格
- 显式网格:通过
grid-template-columns、grid-template-rows等属性明确定义的网格。 - 隐式网格:当现有显式网格无法容纳项目,或项目被定位到显式网格之外时,浏览器自动补充的网格轨道。
2. grid-auto-rows
.container { display: grid; grid-template-columns: repeat(3, 100px); grid-auto-rows: 80px; gap: 10px;}这里明确规定了三列,但没有定义显式行轨道。
浏览器会根据项目数量自动创建行,每条自动创建的行轨道高 80px。
例如有 9 个项目,就会自动排列成 3 行 3 列。
3. grid-auto-columns
.container { display: grid; grid-template-rows: repeat(2, 100px); grid-auto-flow: column; grid-auto-columns: 150px; gap: 10px;}这里定义了两行,项目按照列方向排列。
当需要新的列时,浏览器会自动创建隐式列轨道,每列宽 150px。
容易混淆的区别:
grid-template-rows / columns:定义显式网格轨道。grid-auto-rows / columns:控制自动创建的隐式轨道尺寸。grid-auto-flow:控制项目的自动放置方向及是否尝试填补空位。
grid-auto-rows 和 grid-auto-columns 并不是用来指定创建多少行、多少列的。
五、row-gap / column-gap / gap
这三个属性用于设置相邻网格轨道之间的间距。
| 属性 | 说明 |
|---|---|
row-gap | 行轨道之间的间距 |
column-gap | 列轨道之间的间距 |
gap | 两者的简写属性 |
1. 基本使用
.container { display: grid; grid-template-columns: repeat(3, 100px); grid-template-rows: repeat(2, 80px);
row-gap: 10px; column-gap: 20px;}可以简写为:
.container { gap: 10px 20px;}其中:
- 第一个值:
row-gap。 - 第二个值:
column-gap。
如果只设置一个值:
.container { gap: 10px;}表示行间距、列间距均为 10px。
2. 间距和轨道的关系
.container { display: grid; grid-template-columns: 100px 200px; column-gap: 20px;}网格在列方向上的总尺寸为:
100px + 20px + 200px = 320px注意:
gap不属于单元格,也不计入普通轨道自身的尺寸。- 固定尺寸的轨道不会因为设置
gap而自动缩小。 - 如果轨道使用
fr等弹性尺寸,则需要在分配可用空间时考虑gap。 - 当项目跨越多条轨道时,其占据的网格区域包含中间的
gap。
从布局计算角度,也可以把 gap 想象成网格线具有了厚度,但网格线并不是真实可见的边框。
六、grid-template-areas
grid-template-areas 用于通过名称定义网格区域,让布局结构更加直观。
通常与项目属性 grid-area 配合使用。
1. 基本使用
<div class="container"> <header class="header">头部</header> <main class="main">主体</main> <aside class="aside">侧边栏</aside> <footer class="footer">底部</footer></div>.container { display: grid;
grid-template-columns: 200px 1fr; grid-template-rows: 80px 1fr 60px;
grid-template-areas: "header header" "aside main" "footer footer";
gap: 10px; min-height: 500px;}
.header { grid-area: header;}
.main { grid-area: main;}
.aside { grid-area: aside;}
.footer { grid-area: footer;}布局结构为:
┌─────────────────┐│ header │├───────┬─────────┤│ aside │ main │├───────┴─────────┤│ footer │└─────────────────┘2. 使用规则
- 同名区域必须组成一个连续的矩形。
- 一个区域可以占据一个或多个单元格。
- 使用
.可以表示不属于任何命名区域的单元格。 - 每行必须声明相同数量的单元格名称或占位符。
grid-template-areas可以建立显式网格结构,即使没有另外设置行高、列宽。
例如:
grid-template-areas: "header header" "main .";其中 . 表示未命名的单元格。
注意:区域不是新的 HTML 元素,也不会真正合并单元格,只是定义了项目可以占据的网格空间。
七、align-items / justify-items / place-items
这三个属性用于控制 Grid 项目在各自网格区域内的对齐方式。
| 属性 | 说明 |
|---|---|
align-items | 控制项目在块级方向的对齐,常见水平书写模式下为垂直方向 |
justify-items | 控制项目在行内方向的对齐,常见水平书写模式下为水平方向 |
place-items | 两者的简写属性 |
1. 常用属性值
| 属性值 | 说明 |
|---|---|
normal | 默认值,在常见 Grid 场景中通常表现为拉伸 |
start | 靠起始位置对齐 |
end | 靠结束位置对齐 |
center | 居中对齐 |
stretch | 拉伸项目以填充可用空间,受尺寸约束影响 |
2. 基本使用
.container { display: grid; grid-template-columns: repeat(3, 150px); grid-template-rows: 150px;
align-items: center; justify-items: center;}表示让所有项目在各自的网格区域内水平、垂直居中。
可以简写为:
.container { place-items: center;}3. place-items 的两个值
.container { place-items: start end;}等价于:
.container { align-items: start; justify-items: end;}第一个值控制 **align-items**,第二个值控制 **justify-items**。
注意:
这三个都是容器属性,统一控制项目在网格区域中的对齐方式。
如果希望单独控制某个项目,可以使用项目属性:
align-selfjustify-selfplace-self
另外,项目的对齐不等于项目内部文字的对齐。
八、align-content / justify-content / place-content
这三个属性用于控制整个网格轨道集合在容器中的对齐和分布方式。
与 *-items 不同,*-content 调整的是网格轨道整体的位置或间距。
| 属性 | 说明 |
|---|---|
align-content | 控制网格轨道集合在块级方向上的对齐和分布 |
justify-content | 控制网格轨道集合在行内方向上的对齐和分布 |
place-content | 两者的简写属性 |
1. 常用属性值
| 属性值 | 说明 |
|---|---|
normal | 默认值,在常见 Grid 场景中效果通常接近 stretch |
start | 靠起始位置排列 |
end | 靠结束位置排列 |
center | 居中排列 |
space-between | 首尾贴边,剩余空间分布在轨道之间 |
space-around | 每条轨道两侧分配相等的空间份额 |
space-evenly | 轨道之间及两端的空隙相等 |
stretch | 在适用条件下拉伸可自动调整尺寸的轨道 |
2. 基本使用
.container { display: grid;
width: 500px; height: 400px;
grid-template-columns: repeat(2, 100px); grid-template-rows: repeat(2, 80px);
gap: 10px;
align-content: center; justify-content: center;}这里网格轨道集合的宽度为 210px,高度为 170px。
由于容器宽 500px、高 400px,还存在剩余空间,因此可以将整个网格居中。
可以简写为:
.container { place-content: center;}3. place-content 的两个值
.container { place-content: start center;}等价于:
.container { align-content: start; justify-content: center;}4. items 和 content 的区别
这是 Grid 中容易混淆的一组属性。
| 对比 | *-items | *-content |
|---|---|---|
| 控制对象 | 各个 Grid 项目 | 整个网格轨道集合 |
| 主要作用 | 控制项目在网格区域中的对齐 | 控制轨道集合在容器中的对齐和分布 |
| 常见用法 | place-items: center | place-content: center |
| 是否控制项目内部文字 | 否 | 否 |
简单记忆:
items:调整项目的位置。content:调整网格轨道整体的位置及分布。
注意:align-content、justify-content 并不是任何时候都能明显改变布局。
例如,使用 1fr 的轨道可能已经占满可用空间,此时没有剩余空间供这些属性分配,对齐效果就可能不明显。
九、grid-template / grid
这两个都是 Grid 的简写属性,用于同时设置多个网格布局相关属性。
1. grid-template
grid-template 是以下三个属性的简写:
grid-template-rowsgrid-template-columnsgrid-template-areas
基本写法:
.container { display: grid;
grid-template: 80px 120px / 100px 200px;}等价于:
.container { grid-template-rows: 80px 120px; grid-template-columns: 100px 200px;}也可以同时定义命名区域:
.container { display: grid;
grid-template: "header header" 80px "aside main" 1fr / 200px 1fr;}这里:
- 第一行高
80px。 - 第二行占据剩余的弹性空间。
- 第一列宽
200px。 - 第二列使用
1fr。 - 同时定义了
header、aside、main三个区域。
2. grid
grid 是范围更广的简写属性,可以同时设置显式网格和隐式网格相关配置。
它涉及:
grid-template-rowsgrid-template-columnsgrid-template-areasgrid-auto-rowsgrid-auto-columnsgrid-auto-flow
例如:
.container { display: grid;
grid: 80px 120px / 100px 200px;}这会定义两条显式行轨道和两条显式列轨道,同时将相关的其他 Grid 子属性重置为初始值。
3. 两者的区别
| 属性 | 作用 |
|---|---|
grid-template | 主要定义显式网格的行、列及命名区域 |
grid | 既能定义显式网格,也能配置部分隐式网格规则 |
注意:
grid的写法较灵活,但语法也更复杂。grid不包含gap、align-items、justify-items等对齐和间距属性。- 使用简写时要注意其他相关子属性可能被重置。
实际开发中,通常更推荐分别使用 grid-template-columns、grid-template-rows、grid-auto-flow 等属性,方便阅读和维护。
总结
| 属性 | 核心作用 |
|---|---|
display | 创建 Grid 容器 |
grid-template-rows | 定义显式行轨道及其高度 |
grid-template-columns | 定义显式列轨道及其宽度 |
grid-auto-flow | 控制自动放置项目的方向和填补规则 |
grid-auto-rows | 设置隐式行轨道尺寸 |
grid-auto-columns | 设置隐式列轨道尺寸 |
row-gap | 设置行轨道间距 |
column-gap | 设置列轨道间距 |
gap | 设置行、列轨道间距 |
grid-template-areas | 定义命名网格区域 |
align-items | 控制项目在块级方向的对齐 |
justify-items | 控制项目在行内方向的对齐 |
place-items | 简写项目对齐方式 |
align-content | 控制轨道集合在块级方向的对齐和分布 |
justify-content | 控制轨道集合在行内方向的对齐和分布 |
place-content | 简写轨道集合的对齐和分布方式 |
grid-template | 显式网格结构的简写 |
grid | 显式及隐式网格相关配置的综合简写 |
Grid 容器属性可以归纳为四类:
- 结构与尺寸:定义行列轨道及其宽高。
- 自动排列:决定项目如何自动放置,以及隐式轨道如何确定尺寸。
- 间距与区域:控制轨道间隔和项目的布局区域。
- 对齐与分布:控制项目在网格区域中的位置,以及网格轨道整体在容器中的位置。
理解这四类属性的职责后,Grid 容器属性就不再是零散的 CSS 语法,而是一套有明确分工的布局规则。
Grid 项目的属性
Grid 项目属性主要用于控制项目在网格中的位置、跨行跨列的范围,以及项目在网格区域内的对齐方式。
Grid 项目通常是 Grid 容器中参与网格布局的直接子元素。
一、grid-column-start / grid-column-end / grid-row-start / grid-row-end
这四个属性用于通过**网格线(Grid Line)**确定项目的起始位置和结束位置。
| 属性 | 说明 |
|---|---|
grid-column-start | 项目在列方向的起始网格线 |
grid-column-end | 项目在列方向的结束网格线 |
grid-row-start | 项目在行方向的起始网格线 |
grid-row-end | 项目在行方向的结束网格线 |
1. 基本使用
首先创建一个 3 行 3 列的网格:
.container { display: grid; grid-template-columns: repeat(3, 100px); grid-template-rows: repeat(3, 100px); gap: 10px;}然后指定项目的位置:
.item { grid-column-start: 1; grid-column-end: 3; grid-row-start: 1; grid-row-end: 3;}表示:
- 列方向:从第 1 条列网格线到第 3 条列网格线,跨越 2 列。
- 行方向:从第 1 条行网格线到第 3 条行网格线,跨越 2 行。
- 最终项目占据 2 行 2 列,共 4 个单元格对应的矩形区域。
注意:指定的是网格线编号,而不是单元格编号。
例如一个 3 行 3 列的显式网格,在两个方向上分别有 4 条网格线。
2. 常用属性值
| 属性值 | 说明 |
|---|---|
auto | 默认值,由自动布局规则确定位置或范围 |
1、2、3 | 指定网格线编号 |
-1 | 从显式网格末端反向编号,表示最后一条显式网格线 |
span 2 | 从相应位置跨越 2 条轨道 |
header | 引用符合规则的命名网格线或区域名称 |
例如:
.item { grid-column-start: 1; grid-column-end: span 2;}表示项目从第 1 条列网格线开始,横跨 2 列。
还可以通过负数引用显式网格的末端网格线:
.item { grid-column-start: 1; grid-column-end: -1;}这里表示从第 1 条列网格线延伸到显式网格的最后一条列网格线。
二、grid-column / grid-row
grid-column 和 grid-row 是起始、结束网格线属性的简写。
| 简写属性 | 对应属性 |
|---|---|
grid-column | grid-column-start、grid-column-end |
grid-row | grid-row-start、grid-row-end |
1. 基本使用
.item { grid-column: 1 / 3; grid-row: 1 / 3;}等价于:
.item { grid-column-start: 1; grid-column-end: 3;
grid-row-start: 1; grid-row-end: 3;}其中 / 用于分隔起始位置和结束位置。
2. 常见写法
| 写法 | 说明 |
|---|---|
grid-column: 1 / 3 | 从第 1 条列网格线到第 3 条,跨越 2 列 |
grid-column: 1 / 4 | 从第 1 条列网格线到第 4 条,跨越 3 列 |
grid-column: 2 | 从第 2 条列网格线开始,通常跨越 1 列 |
grid-column: 1 / span 2 | 从第 1 条列网格线开始,跨越 2 列 |
grid-column: span 2 | 跨越 2 列,起始位置可由自动布局确定 |
grid-column: 1 / -1 | 从第 1 条列网格线到显式网格最后一条列网格线 |
grid-row 的使用方式相同,只是控制行方向。
3. 跨列和跨行
跨列:
.item { grid-column: span 2;}表示项目横跨 2 条列轨道。
跨行:
.item { grid-row: span 2;}表示项目横跨 2 条行轨道。
同时跨行、跨列:
.item { grid-column: 1 / 3; grid-row: 1 / 3;}表示项目占据一个 2 行 2 列的矩形区域。
需要注意:
- 项目跨越多个单元格,并不意味着单元格被真正合并。
- 项目跨越的区域包含中间的
gap。 - 项目定位后,如果与其他项目占据相同区域,可能发生重叠。
三、grid-area
grid-area 用于指定 Grid 项目所在的网格区域。
它既可以引用命名区域,也可以作为四个网格线定位属性的简写。
1. 使用命名区域
首先通过容器属性 grid-template-areas 定义区域:
.container { display: grid;
grid-template-columns: 200px 1fr; grid-template-rows: 80px 200px;
grid-template-areas: "header header" "aside main";}然后通过项目属性 grid-area 指定位置:
.header { grid-area: header;}
.aside { grid-area: aside;}
.main { grid-area: main;}其中:
header:占据第一行的两列。aside:占据第二行第一列。main:占据第二行第二列。
**grid-template-areas** 是容器属性,**grid-area** 是项目属性。
2. 使用网格线定位
grid-area 还可以直接指定四条网格线:
.item { grid-area: 1 / 2 / 3 / 4;}其顺序为:
grid-area: row-start / column-start / row-end / column-end;对应:
.item { grid-row-start: 1; grid-column-start: 2; grid-row-end: 3; grid-column-end: 4;}表示项目:
- 从第 1 条行网格线到第 3 条行网格线。
- 从第 2 条列网格线到第 4 条列网格线。
最终横跨 2 行、2 列。
3. grid-area 与 grid-column、grid-row 的区别
| 属性 | 作用 |
|---|---|
grid-column | 控制项目在列方向的位置与范围 |
grid-row | 控制项目在行方向的位置与范围 |
grid-area | 可以同时控制行列位置,也可以引用命名区域 |
例如:
.item { grid-column: 2 / 4; grid-row: 1 / 3;}可以写成:
.item { grid-area: 1 / 2 / 3 / 4;}注意:区域是布局空间,项目是实际元素。使用 **grid-area** 不会真正创建或合并 HTML 元素。
四、align-self / justify-self / place-self
这三个属性用于控制单个 Grid 项目在其网格区域内的对齐方式。
| 属性 | 说明 |
|---|---|
align-self | 控制项目在块级方向上的对齐,通常是垂直方向 |
justify-self | 控制项目在行内方向上的对齐,通常是水平方向 |
place-self | 两者的简写属性 |
这里的水平、垂直方向是基于常见的水平书写模式而言的。
1. 常用属性值
| 属性值 | 说明 |
|---|---|
auto | 默认值,继承容器对应的 align-items 或 justify-items 效果 |
start | 靠网格区域的起始位置对齐 |
end | 靠网格区域的结束位置对齐 |
center | 在网格区域内居中 |
stretch | 拉伸项目以填充对应方向的可用空间,受尺寸限制影响 |
2. align-self
用于控制单个项目在块级方向上的对齐。
.container { display: grid; grid-template-columns: repeat(3, 150px); grid-template-rows: 150px;}
.item { align-self: center;}在常见水平书写模式下,项目会在所在网格区域内垂直居中。
3. justify-self
用于控制单个项目在行内方向上的对齐。
.item { justify-self: center;}在常见水平书写模式下,项目会在所在网格区域内水平居中。
4. place-self
place-self 是 align-self 和 justify-self 的简写属性。
.item { place-self: center;}等价于:
.item { align-self: center; justify-self: center;}也可以指定两个值:
.item { place-self: start end;}等价于:
.item { align-self: start; justify-self: end;}第一个值对应 **align-self**,第二个值对应 **justify-self**。
5. items 和 self 的区别
Grid 容器属性中还有一组非常相似的属性:
align-itemsjustify-itemsplace-items
它们和项目属性的对应关系如下:
| 容器属性 | 项目属性 |
|---|---|
align-items | align-self |
justify-items | justify-self |
place-items | place-self |
区别:
*-items:设置在 Grid 容器上,统一控制项目的对齐。*-self:设置在 Grid 项目上,单独控制某个项目的对齐。
例如:
.container { display: grid; grid-template-columns: repeat(3, 150px); grid-template-rows: 150px;
place-items: center;}
.item-2 { place-self: start;}这里所有项目默认在各自的网格区域内居中,但 .item-2 单独靠起始位置对齐。
注意:
这组属性控制的是项目自身在网格区域中的对齐,不是项目内部文字的对齐。
如果项目设置了固定宽高,对齐效果通常更容易观察;如果项目默认拉伸填充整个网格区域,视觉上可能不容易看出位置变化。
总结
| 属性 | 主要作用 |
|---|---|
grid-column-start | 设置列方向起始网格线 |
grid-column-end | 设置列方向结束网格线 |
grid-row-start | 设置行方向起始网格线 |
grid-row-end | 设置行方向结束网格线 |
grid-column | 简写列方向的起始、结束网格线 |
grid-row | 简写行方向的起始、结束网格线 |
grid-area | 指定命名区域或简写四条网格线 |
align-self | 单独控制项目在块级方向上的对齐 |
justify-self | 单独控制项目在行内方向上的对齐 |
place-self | 简写项目自身的两个方向对齐方式 |
Grid 项目属性可以归纳为两个类别:
- 位置与范围:通过
grid-column-*、grid-row-*、grid-area决定项目放在哪里、占据多少行列。 - 自身对齐:通过
align-self、justify-self、place-self控制项目在所占网格区域中的位置。
最重要的是区分:
- 网格定位:项目占据网格中的哪一块区域。
- 项目对齐:项目在已经占据的区域内如何对齐。
简单理解:先通过网格线确定项目的布局区域,再通过对齐属性调整项目在该区域中的位置。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!














