CSS Grid 布局
CSS Grid(网格) 布局(又称为 “Grid(网格)” ),是一个二维的基于网格的布局系统它的目标是完全改变我们基于网格的用户界面的布局方式。
网格容器(Grid Container)
应用 display: grid
的元素。这是所有网格项(Grid Items)的直接父级元素。在这个例子中,container
就是网格容器(Grid Container)。
举例:
<div class="container">
<div class="item item-1"></div>
<div class="item item-2"></div>
<div class="item item-3"></div>
</div>
网格项(Grid Item)
网格容器(Grid Container)的子元素(直接子元素)。这里item
元素就是网格项(Grid Item),但是 sub-item
不是。
举例
<div class="container">
<div class="item"></div>
<div class="item">
<p class="sub-item"></p> //不是网格项(Grid Item)
</div>
<div class="item"></div>
</div>
网格线(Grid Line)
构成网格结构的分界线。它们既可以是垂直的(“列网格线(column grid lines)”),也可以是水平的(“行网格线(row grid lines)”),并位于行或列的任一侧。例如,这里的黄线就是一条列网格线。
![](https://img.haomeiwen.com/i126164/c2857d217aae89d6.png)
网格轨道(Grid Track)
两条相邻网格线之间的空间。你可以把它们想象成网格的列或行。下图是第二条和第三条 行网格线 之间的 网格轨道(Grid Track)。
![](https://img.haomeiwen.com/i126164/a66c3f869c5cbd91.png)
网格单元格(Grid Cell)
两个相邻的行和两个相邻的列网格线之间的空间。这是 Grid(网格) 系统的一个“单元”。下图是第1至第2条 行网格线 和第2至第3条 列网格线 交汇构成的 网格单元格(Grid Cell)。
![](https://img.haomeiwen.com/i126164/f53127d71a81ffc3.png)
网格区域(Grid Area)
4条网格线包围的总空间。一个 网格区域(Grid Area) 可以由任意数量的 网格单元格(Grid Cell) 组成。下图是 行网格线1和3,以及列网格线1和3 之间的网格区域。
![](https://img.haomeiwen.com/i126164/58bf1022f087f43e.png)
父元素 网格容器(Grid Container) 属性
1. display
将元素定义为网格容器,并为其内容建立新的 网格格式上下文。
值:
-
grid :生成一个块级网格
-
inline-grid :生成一个内联网格
-
subgrid :如果你的网格容器本身是另一个网格的网格项(即嵌套网格),你可以使用这个属性来表示
你希望它的行/列的大小继承自它的父级网格容器,而不是自己指定的。
如果你想要设置为网格容器元素本身已经是网格项(嵌套网格布局),用这个属性指明这个容器内部的网格项的行列尺寸直接继承其父级的网格容器属性。
.container {
display: grid | inline-grid | subgrid;
}
注意:在 网格容器(Grid Container) 上使用column
,float
,clear
, vertical-align
不会产生任何效果。
2. grid-template-columns / grid-template-rows
使用空格分隔的值列表,用来定义网格的列和行。这些值表示 网格轨道(Grid Track) 大小,它们之间的空格表示网格线。
值:
- <track-size>: 可以是长度值,百分比,或者等份网格容器中可用空间(使用 fr 单位)
- <line-name>:你可以选择的任意名称
.container {
grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
}
举例:
.container{
grid-template-columns: 40px 50px auto 50px 40px; //表示一共5列
grid-template-rows: 25% 100px auto; //表示一共3行
}
![](https://img.haomeiwen.com/i126164/c30dac461bcb8a10.png)
但是你可以明确的指定网格线(Grid Line)名称,即 <line-name> 值。请注意网格线名称的括号语法:
.container {
grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
}
![](https://img.haomeiwen.com/i126164/6f097df166805997.png)
请注意,一条网格线(Grid Line)可以有多个名称。例如,这里的第二条 行网格线(row grid lines) 将有两个名字:row1-end 和row2-start :
.container{
grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];
}
如果你的定义包含多个重复值,则可以使用 repeat()
表示法来简化定义:
.container {
grid-template-columns: repeat(3, 20px [col-start]) 5%;
}
上面的代码等价于:
.container {
grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start] 5%;
}
fr
单元允许你用等分网格容器剩余可用空间来设置 网格轨道(Grid Track) 的大小 。例如,下面的代码会将每个网格项设置为网格容器宽度的三分之一:
.container {
grid-template-columns: 1fr 1fr 1fr;
}
剩余可用空间是除去所有非灵活网格项之后计算得到的。在这个例子中,可用空间总量减去 50px 后,再给 fr
单元的值3等分:
.container {
grid-template-columns: 1fr 50px 1fr 1fr;
}
3.grid-template-areas
通过引用 grid-area
属性指定的 网格区域(Grid Area) 名称来定义网格模板。重复网格区域的名称导致内容跨越这些单元格。一个点号(.
)代表一个空的网格单元。这个语法本身可视作网格的可视化结构。
值:
-
<grid-area-name>:由网格项的
grid-area
指定的网格区域名称 - .(点号) :代表一个空的网格单元
-
none:不定义网格区域
示例:
.container {
grid-template-columns: 50px 50px 50px 50px;
grid-template-rows: auto;
grid-template-areas:
"header header header header"
"main main . sidebar"
"footer footer footer footer";
}
.item-a {
grid-area: header;
}
.item-b {
grid-area: main;
}
.item-c {
grid-area: sidebar;
}
.item-d {
grid-area: footer;
}
上面的代码将创建一个 4 列 3 行的网格。整个顶行将由 header 区域 组成。中间一排将由两个 main 区域,一个是空单元格,一个 sidebar 区域组成。最后一行全是 footer 区域组成。
![](https://img.haomeiwen.com/i126164/aedf2e2bedf7cdf6.png)
你的声明中的每一行都需要有相同数量的单元格。
4. grid-template
用于定义 grid-template-rows
,grid-template-columns
,grid-template-areas
缩写属性。
值:
- none:将所有三个属性设置为其初始值
-
subgrid:将
grid-template-rows
,grid-template-columns
的值设为subgrid
,grid-template-areas
设为初始值 -
<grid-template-rows> / <grid-template-columns>:将
grid-template-columns
和grid-template-rows
设置为相应地特定的值,并且设置grid-template-areas
为none
例子:
.container {
grid-template:
"header header header" 25px // 行高 rows
"footer footer footer" 25px // 行高 rows
/ auto 50px auto; // 列宽 columns
}
等价于:
.container {
grid-template-rows: 25px 25px;
grid-template-columns: auto 50px auto;
grid-template-areas:
"header header header"
"footer footer footer";
}
由于 grid-template
不会重置 隐式 网格属性(grid-auto-columns
, grid-auto-rows
, 和 grid-auto-flow
),
这可能是你想在大多数情况下做的,建议使用 grid
属性而不是 grid-template
。
5. grid-column-gap / grid-row-gap
指定网格线(grid lines)的大小。你可以把它想象为设置列/行之间间距的宽度。
示例:
.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
grid-column-gap: 10px; // 列与列间隙 10px
grid-row-gap: 15px; //行与行间隙15px
}
![](https://img.haomeiwen.com/i126164/51e316b1f6572d22.png)
注:只能在 列/行 之间创建间距,网格外部边缘不会有这个间距。
6. grid-gap
grid-column-gap
和 grid-row-gap
的缩写语法
值:
- <grid-row-gap> <grid-column-gap>:长度值
示例:
.container{
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
grid-gap: 10px 15px; // <grid-row-gap> <grid-column-gap>;
}
7. justify-items
沿着 行轴线(row axis) 对齐 网格项(grid items) 内的内容(相反的属性是 align-items
沿着列轴线对齐)。该值适用于容器内的所有网格项。
值:
- start:将内容对齐到网格区域(grid area)的左侧
- end:将内容对齐到网格区域的右侧
- center:将内容对齐到网格区域的中间(水平居中)
- stretch:填满网格区域宽度(默认值)
.container {
justify-items: start | end | center | stretch;
}
示例:
.container {
justify-items: start;
}
![](https://img.haomeiwen.com/i126164/0ffdd0537ad3094f.png)
.container{
justify-items: end;
}
![](https://img.haomeiwen.com/i126164/476de78a5f3c8b15.png)
.container{
justify-items: center;
}
![](https://img.haomeiwen.com/i126164/5b4bab5c35b545c1.png)
.container{
justify-items: stretch;
}
![](https://img.haomeiwen.com/i126164/be4e10b3190b81ba.png)
这些行为也可以通过单独网格项(grid items) 的 justify-self
属性设置。
8. align-items
沿着 列轴线(column axis) 对齐 网格项(grid items) 内的内容(相反的属性是 justify-items
沿着行轴线对齐)。该值适用于容器内的所有网格项。
值:
- start:将内容对齐到网格区域(grid area)的顶部
- end:将内容对齐到网格区域的底部
- center:将内容对齐到网格区域的中间(垂直居中)
- stretch:填满网格区域高度(默认值)
.container {
align-items: start | end | center | stretch;
}
示例:
.container {
align-items: start;
}
![](https://img.haomeiwen.com/i126164/b94336c0b9610971.png)
.container {
align-items: end;
}
![](https://img.haomeiwen.com/i126164/8734fe0660b8cba3.png)
.container {
align-items: center;
}
![](https://img.haomeiwen.com/i126164/7219243a92297eb9.png)
.container {
align-items: stretch;
}
![](https://img.haomeiwen.com/i126164/19e41097da601012.png)
这些行为也可以通过单独网格项(grid items) 的 align-self
属性设置。
9. justify-content
有时,你的网格合计大小可能小于其 网格容器(grid container) 大小。 如果你的所有 网格项(grid items) 都使用像 px
这样的非灵活单位设置大小,在这种情况下,您可以设置网格容器内的网格的对齐方式。 此属性沿着 行轴线(row axis) 对齐网格(相反的属性是 align-content
,沿着列轴线对齐网格)。
值:
- start:将网格对齐到 网格容器(grid container) 的左边
- end:将网格对齐到 网格容器 的右边
- center:将网格对齐到 网格容器 的中间(水平居中)
- stretch:调整 网格项(grid items) 的宽度,允许该网格填充满整个 网格容器 的宽度
- space-around:在每个网格项之间放置一个均匀的空间,左右两端放置一半的空间
- space-between:在每个网格项之间放置一个均匀的空间,左右两端没有空间
- space-evenly:在每个栅格项目之间放置一个均匀的空间,左右两端放置一个均匀的空间
.container {
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
示例:
.container {
justify-content: start;
}
![](https://img.haomeiwen.com/i126164/e8c3553d8921810b.png)
.container {
justify-content: end;
}
![](https://img.haomeiwen.com/i126164/8995abdef8e07454.png)
.container {
justify-content: center;
}
![](https://img.haomeiwen.com/i126164/4ff78442b6237eaf.png)
.container {
justify-content: stretch;
}
![](https://img.haomeiwen.com/i126164/bb5ce746a5f457bc.png)
.container {
justify-content: space-around;
}
![](https://img.haomeiwen.com/i126164/b687659fd29e3297.png)
.container {
justify-content: space-between;
}
![](https://img.haomeiwen.com/i126164/d632ac139c44effc.png)
CSS 代码:
.container {
justify-content: space-evenly;
}
![](https://img.haomeiwen.com/i126164/f58aa4ebad8eede8.png)
10. align-content
有时,你的网格合计大小可能小于其 网格容器(grid container) 大小。 如果你的所有 网格项(grid items) 都使用像 px
这样的非灵活单位设置大小,在这种情况下,您可以设置网格容器内的网格的对齐方式。 此属性沿着 列轴线(column axis) 对齐网格(相反的属性是 justify-content
,沿着行轴线对齐网格)。
值:
- start:将网格对齐到 网格容器(grid container) 的顶部
- end:将网格对齐到 网格容器 的底部
- center:将网格对齐到 网格容器 的中间(垂直居中)
- stretch:调整 网格项(grid items) 的高度,允许该网格填充满整个 网格容器 的高度
- space-around:在每个网格项之间放置一个均匀的空间,上下两端放置一半的空间
- space-between:在每个网格项之间放置一个均匀的空间,上下两端没有空间
- space-evenly:在每个栅格项目之间放置一个均匀的空间,上下两端放置一个均匀的空间
.container {
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
示例:
.container {
align-content: start;
}
![](https://img.haomeiwen.com/i126164/ac26e444112f13f6.png)
.container {
2\. align-content: end;
}
![](https://img.haomeiwen.com/i126164/0ccd3611455e5e6f.png)
.container {
align-content: center;
}
![](https://img.haomeiwen.com/i126164/441a94415f9becd6.png)
.container {
align-content: stretch;
}
![](https://img.haomeiwen.com/i126164/080ee0c5b6f1fb97.png)
.container {
align-content: space-around;
}
![](https://img.haomeiwen.com/i126164/7c01cdb26962521e.png)
.container {
align-content: space-between;
}
![](https://img.haomeiwen.com/i126164/9d611b29cb755a26.png)
CSS 代码:
.container {
align-content: space-evenly;
}
![](https://img.haomeiwen.com/i126164/f5af8c93e9a0338d.png)
11. grid-auto-columns / grid-auto-rows
指定任何自动生成的网格轨道(grid tracks)(又名隐式网格轨道)的大小。在你明确定位的行或列(通过 grid-template-rows
/ grid-template-columns
),超出定义的网格范围时,隐式网格轨道被创建了。
值:
– <track-size>:可以是长度值,百分比,或者等份网格容器中可用空间(使用 fr
单位)
.container {
grid-auto-columns: <track-size> ...;
grid-auto-rows: <track-size> ...;
}
为了说明如何创建隐式网格轨道,请考虑一下以下的代码:
.container {
grid-template-columns: 60px 60px;
grid-template-rows: 90px 90px
}
![](https://img.haomeiwen.com/i126164/a30923a81070d0c6.png)
生成了一个2×2的网格。
但现在想象一下,你使用 grid-column
和 grid-row
来定位你的网格项(grid items),像这样:
.item-a {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
.item-b {
grid-column: 5 / 6;
grid-row: 2 / 3;
}
![](https://img.haomeiwen.com/i126164/61dea8fe963775e6.png)
我们告诉 .item-b
从第 5 条列网格线开始到第 6 条列网格线结束,但我们从来没有定义过 第5 或 第6 列网格线。
因为我们引用的网格线不存在,所以创建宽度为 0 的隐式网格轨道以填补空缺。我们可以使用 grid-auto-columns
和 grid-auto-rows
来指定这些隐式轨道的大小:
.container {
grid-auto-columns: 60px;
}
![](https://img.haomeiwen.com/i126164/26e6cdd23f55e7d0.png)
12. grid-auto-flow
如果你有一些没有明确放置在网格上的网格项(grid items),自动放置算法 会自动放置这些网格项。该属性控制自动布局算法如何工作。
值:
- row:告诉自动布局算法依次填充每行,根据需要添加新行
- column:告诉自动布局算法依次填入每列,根据需要添加新列
- dense:告诉自动布局算法在稍后出现较小的网格项时,尝试填充网格中较早的空缺
.container {
grid-auto-flow: row | column | row dense | column dense
}
请注意,dense
集可能导致你的网格项出现乱序。
示例:
考虑以下 HTML :
<section class="container">
<div class="item-a">item-a</div>
<div class="item-b">item-b</div>
<div class="item-c">item-c</div>
<div class="item-d">item-d</div>
<div class="item-e">item-e</div>
</section>
你定义一个有 5 列和 2 行的网格,并将 grid-auto-flow
设置为 row
(也就是默认值):
.container {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px;
grid-template-rows: 30px 30px;
grid-auto-flow: row;
}
将网格项放在网格上时,只能为其中的两个指定位置:
CSS 代码:
.item-a {
grid-column: 1;
grid-row: 1 / 3;
}
.item-e {
grid-column: 5;
grid-row: 1 / 3;
}
因为我们把 grid-auto-flow
设成了 row
,所以我们的网格看起来会是这样。注意 我们没有进行定位的网格项(item-b
,item-c
,item-d
)会这样排列在可用的行中:
![](https://img.haomeiwen.com/i126164/6c0c1fa7d7f7f57a.png)
相反地,如果我们把 grid-auto-flow
设成了 column
,item-b
,item-c
,item-d
会沿着列向下排列:
.container {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px;
grid-template-rows: 30px 30px;
grid-auto-flow: column;
}
![](https://img.haomeiwen.com/i126164/7f7b452fc71d23ef.png)
13. grid
在一个声明中设置所有以下属性的简写: grid-template-rows
, grid-template-columns
, grid-template-areas
, grid-auto-rows
, grid-auto-columns
, 和 grid-auto-flow
。它还将grid-column-gap
和 grid-column-gap
设置为初始值,即使它们不可以通过grid
属性显式地设置。
值:
- none:将所有子属性设置为其初始值
- <grid-template-rows> / <grid-template-columns>:将
grid-template-rows
和grid-template-columns
分别设置为指定值,将所有其他子属性设置为其初始值 - <grid-auto-flow> [<grid-auto-rows> [ / <grid-auto-columns>] ] :分别接受所有与
grid-auto-flow
,grid-auto-rows
和grid-auto-columns
相同的值。如果省略了grid-auto-columns
,它被设置为由grid-auto-rows
指定的值。如果两者都被省略,他们就会被设置为初始值
.container {
grid: none | <grid-template-rows> / <grid-template-columns> | <grid-auto-flow> [<grid-auto-rows> [/ <grid-auto-columns>]];
}
例子:
以下两个代码块是等效的:
.container {
grid: 200px auto / 1fr auto 1fr;
}
.container {
grid-template-rows: 200px auto;
grid-template-columns: 1fr auto 1fr;
grid-template-areas: none;
}
以下两个代码块也是等效的:
.container {
grid: column 1fr / auto;
}
.container {
grid-auto-flow: column;
grid-auto-rows: 1fr;
grid-auto-columns: auto;
}
它也接受一个更复杂但相当方便的语法来一次设置所有内容。您可以 grid-template-areas
,grid-template-rows
和grid-template-columns
,并所有其他的子属性都被设置为它们的初始值。这么做可以在它们网格区域内相应地指定网格线名字和网格轨道的大小。用最简单的例子来描述:
.container {
grid: "header header header" 1fr
"footer footer footer" 25px
/ auto 50px auto;
}
等价于:
.container {
grid-template-areas:
"header header header"
"footer footer footer";
grid-template-rows: 1fr 25px ;
grid-template-columns: auto 50px auto;
}
子元素 网格项(Grid Items) 属性
1. grid-column-start / grid-column-end / grid-row-start / grid-row-end
通过指定 网格线(grid lines) 来确定网格内 网格项(grid item) 的位置。 grid-column-start
/ grid-row-start
是网格项目开始的网格线,grid-column-end
/ grid-row-end
是网格项结束的网格线。
值:
-
<line> :可以是一个数字引用一个编号的网格线,或者一个名字来引用一个命名的网格线
-
span <number> :该网格项将跨越所提供的网格轨道数量
-
span <name> :该网格项将跨越到它与提供的名称位置
-
auto :表示自动放置,自动跨度,默认会扩展一个网格轨道的宽度或者高度
示例:
.item-a {
grid-column-start: 2;
grid-column-end: five;
grid-row-start: row1-start
grid-row-end: 3
}
![](https://img.haomeiwen.com/i126164/83413a5061278972.png)
.item-b {
grid-column-start: 1;
grid-column-end: span col4-start;
grid-row-start: 2
grid-row-end: span 2
}
![](https://img.haomeiwen.com/i126164/3b216af79c348e4c.png)
如果没有声明指定 grid-column-end
/ grid-row-end
,默认情况下,该网格项将占据1个轨道。
项目可以相互重叠。您可以使用 z-index
来控制它们的重叠顺序。
2. grid-column / grid-row
分别为 grid-column-start
+ grid-column-end
和 grid-row-start
+ grid-row-end
的缩写形式。
值:
- <start-line> / <end-line>:每个网格项都接受所有相同的值,作为普通书写的版本,包括跨度
.item {
grid-column: <start-line> / <end-line> | <start-line> / span <value>;
grid-row: <start-line> / <end-line> | <start-line> / span <value>;
}
示例:
.item-c {
grid-column: 3 / span 2;
grid-row: third-line / 4;
}
![](https://img.haomeiwen.com/i126164/215d762a889e0113.png)
如果没有声明分隔线结束位置,则该网格项默认占据 1 个网格轨道。
3. grid-area
为网格项提供一个名称,以便可以 被使用网格容器 grid-template-areas
属性创建的模板进行引用。 另外,这个属性可以用作grid-row-start
+ grid-column-start
+ grid-row-end
+ grid-column-end
的缩写。
值:
- <name>:你所选的名称
- <row-start> / <column-start> / <row-end> / <column-end>:数字或分隔线名称
.item {
grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;
}
示例:
作为为网格项分配名称的一种方法:
.item-d {
grid-area: header
}
作为grid-row-start
+ grid-column-start
+ grid-row-end
+ grid-column-end
属性的缩写形式
.item-d {
grid-area: 1 / col4-start / last-line / 6
}
![](https://img.haomeiwen.com/i126164/ee6f5e5c1845954f.png)
4. justify-self
沿着 行轴线(row axis) 对齐 网格项 内的内容( 相反的属性是 align-self
,沿着列轴线(column axis)对齐)。此值适用于单个网格项内的内容。
值:
- start:将内容对齐到网格区域的左侧
- end:将内容对齐到网格区域的右侧
- center:将内容对齐到网格区域的中间(水平居中)
- stretch:填充整个网格区域的宽度(这是默认值)
示例:
.item-a {
justify-self: start;
}
![](https://img.haomeiwen.com/i126164/1877da71ef8c2b57.png)
.item-a {
justify-self: end;
}
![](https://img.haomeiwen.com/i126164/17372753762a0598.png)
.item-a {
justify-self: center;
}
![](https://img.haomeiwen.com/i126164/7c66ff2f4967cd1b.png)
.item-a {
justify-self: stretch;
}
![](https://img.haomeiwen.com/i126164/46c07483baf6041d.png)
要为网格中的所有网格项设置 行轴线(row axis) 线上对齐方式,也可以在 网格容器 上设置 justify-items
属性。
5. align-self
沿着 列轴线(column axis) 对齐 网格项 内的内容( 相反的属性是 justify-self
,沿着 行轴线(row axis) 对齐)。此值适用于单个网格项内的内容。
值:
- start:将内容对齐到网格区域的顶部
- end:将内容对齐到网格区域的底部
- center:将内容对齐到网格区域的中间(垂直居中)
- stretch:填充整个网格区域的高度(这是默认值)
.item{
align-self: start | end | center | stretch;
}
示例:
.item-a {
align-self: start;
}
![](https://img.haomeiwen.com/i126164/0d5afac3d77df311.png)
.item-a {
align-self: end;
}
</pre>
![](https://img.haomeiwen.com/i126164/5e08753f756eafea.png)
.item-a {
align-self: center;
}
![](https://img.haomeiwen.com/i126164/89834313ec3bc002.png)
.item-a {
align-self: stretch;
}
![](https://img.haomeiwen.com/i126164/b47dba4a647bbb5e.png)
要为网格中的所有网格项设置 列轴线(column axis) 上的对齐方式,也可以在 网格容器 上设置 align-items
属性。