CSS Grid Layout Guide | CSS-Tricks
Layoutit Grid — CSS Grids layouts made easy! 偷懒神器
介绍
CSS Grid布局(也称为"Grid"或"CSS Grid")是一个基于二维网格的布局系统,与过去的任何网页布局系统相比,它彻底改变了我们设计用户界面的方式。CSS一直被用于布局我们的网页,但它在这方面的表现并不理想。最初,我们使用表格,然后是浮动、定位和内联块,但所有这些方法本质上都是一种hack,而且缺少了许多重要的功能(例如垂直居中)。Flexbox也是一个非常好的布局工具,但它的单向流动方式在不同的使用情况下有所不同 - 它们实际上可以很好地结合使用!Grid是第一个专门为解决我们一直在处理的布局问题而创建的CSS模块。
本指南的目的是介绍最新版本规范中存在的Grid概念。因此,我不会涵盖过时的Internet Explorer语法(尽管您完全可以在IE 11中使用Grid)或其他历史性的hack。
CSS Grid基础
自2017年3月起,大多数浏览器已经支持原生的、无需前缀的CSS Grid:包括Chrome(包括Android版本)、Firefox、Safari(包括iOS版本)和Opera。而Internet Explorer 10和11支持Grid,但是它们采用的是旧的实现方式和过时的语法。现在是使用Grid构建网页的时候了!
要开始使用Grid,您需要将一个容器元素定义为网格,使用display: grid,使用grid-template-columns和grid-template-rows设置列和行的大小,然后使用grid-column和grid-row将子元素放入网格中。与flexbox类似,网格项目的源代码顺序并不重要。您的CSS可以以任何顺序来放置它们,这使得使用媒体查询轻松重新排列网格变得非常容易。想象一下,只需几行CSS代码,您就可以定义整个页面的布局,然后完全重新排列它以适应不同的屏幕宽度。Grid是迄今为止最强大的CSS模块之一。
重要的CSS Grid术语
在深入探讨网格(Grid)的概念之前,了解相关术语是非常重要的。由于这里涉及的术语在概念上有些相似,如果不首先记住它们在网格规范中的含义,很容易混淆它们。但是不用担心,这些术语并不多。
在进入正题之前,先了解这些术语的定义是很重要的,因为它们会在接下来的内容中频繁出现。
网格容器(Grid Container)
应用了display: grid的元素,它是所有网格项(grid items)的直接父元素。
在这个示例中,容器是网格:
<div class="container">
<div class="item item-1"> </div>
<div class="item item-2"> </div>
<div class="item item-3"> </div>
</div>
网格线(Grid Line)
构成网格结构的分隔线。它们可以是垂直的("列网格线")或水平的("行网格线"),并位于行或列的两侧。在这个示例中,黄色线是列网格线的一个例子。
网格轨道(Grid Track)
相邻网格线之间的空间。可以将其视为网格的列或行。
这是第二行网格线和第三行网格线之间的网格轨道。
网格区域(Grid Area)
由四个网格线包围的总空间。网格区域可以由任意数量的网格单元(grid cells)组成。这是位于第1行网格线和第3行网格线之间,以及第1列网格线和第3列网格线之间的网格区域。
网格项(Grid Item)
网格容器的子元素(即直接子代)。在这个例子中,item元素是网格项,但sub-item不是。
<div class="container">
<div class="item"> </div>
<div class="item">
<p class="sub-item"> </p>
</div>
<div class="item"> </div>
</div>
网格单元(Grid Cell)
相邻行和相邻列网格线之间的空间。它是网格的一个单个"单元"。这是位于第1行网格线和第2行网格线之间,以及第2列网格线和第3列网格线之间的网格单元。
特殊单位和函数
fr
在CSS Grid中,您可能会经常使用许多分数单位,比如1fr。它们的基本意思是“剩余空间的一部分”。因此,类似于以下声明:
grid-template-columns: 1fr 3fr;
大致上表示25%和75%。不过,这些百分比值要比分数单位更为固定。举个例子,如果您给这些基于百分比的列添加了内边距,那么宽度就会超过100%(假设使用content-box盒模型)。与其他单位相比,分数单位在与它们的组合中更加友好,您可以想象一下:
grid-template-columns: 50px min-content 1fr;
Sizing相关
在调整行和列的大小时,您可以使用您习惯使用的所有长度单位,比如px、rem、%等,但您还可以使用关键字:
min-content:内容的最小大小。想象一下一行文字,比如“E pluribus unum”,min-content可能是单词“pluribus”的宽度。
max-content:内容的最大大小。以上面的句子为例,max-content是整个句子的长度。
auto:这个关键字与分数单位非常相似,只不过在分配剩余空间时,它们在大小方面“输给了”分数单位。
分数单位:请参考上文。
fit-content()函数利用可用空间,但不会小于min-content,也不会大于max-content。
minmax()函数的功能正如其名:为长度设置一个最小值和最大值,这在与相对单位结合使用时非常有用。例如,您可能希望列只能收缩到一定程度。这非常有用,很可能就是您所期望的:
grid-template-columns: minmax(100px, 1fr) 3fr;
repeat
repeat()函数可以节省一些输入:
grid-template-columns:
1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
/* easier: */
grid-template-columns:
repeat(8, 1fr);
/* especially when: */
grid-template-columns:
repeat(8, minmax(10px, 1fr));
当与关键字结合使用时,repeat()函数可以变得更加灵活:
auto-fill: 在一行中尽可能放置尽可能多的列,即使它们是空的。auto-fit: 将所有列适应空间。优先将列扩展以填充空间,而不是保留空列。
这是CSS Grid中最著名的代码片段之一,也是有史以来最伟大的CSS技巧之一:
grid-template-columns:
repeat(auto-fit, minmax(250px, 1fr));
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); 是一种使用自适应网格布局的方式,它可以根据可用空间自动调整列的数量,并在每列之间保持最小和最大宽度的范围。
具体来说,这个表达式使用了 repeat() 函数和 minmax() 函数的组合:
repeat(auto-fit, minmax(250px, 1fr)):这里的auto-fit表示自动调整列的数量以适应可用空间,而不会导致溢出或换行。它会根据容器的宽度自动计算可以容纳的列数。minmax(250px, 1fr):这个函数表示列的宽度可以在 250px 和 1fr(剩余空间的等分)之间进行调整。列的最小宽度是 250px,最大宽度是剩余空间的等分,即自动平均分配剩余的可用空间。
这个表达式的效果是,网格布局会根据可用空间动态调整列的数量,并且每个列的宽度会在最小值和最大值之间自适应调整。当容器宽度增加时,会自动添加更多的列,并且每个列会相应地变窄,以保持整体布局的平衡。
这种技术通常用于创建响应式网格布局,使网格可以根据不同设备和屏幕尺寸自动适应,并具有灵活的列宽度调整能力。
Masonry(实验性)
CSS Grid的一项实验性功能是砌体布局(masonry layout)。请注意,对于CSS砌体布局,有很多方法可供选择(可参考链接:CSS砌体布局的不同方法),但它们大多是一些技巧,要么有重大缺陷,要么与您的期望不完全一致。
规范现在已经有了官方的实现方式,而这在Firefox浏览器中是通过标志开启的。
.container {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: masonry;
}
Subgrid(Firefox only)
Subgrid是网格布局中非常有用的功能,它允许网格项拥有自己的网格,并从父网格继承网格线。
.parent-grid {
display: grid;
grid-template-columns: repeat(9, 1fr);
}
.grid-item {
grid-column: 2 / 7;
display: grid;
grid-template-columns: subgrid;
}
.child-of-grid-item {
/* gets to participate on parent grid! */
grid-column: 3 / 6;
}
目前只有Firefox支持这一功能,但它确实应该得到广泛应用。
另外,了解display: contents;也是很有用的。虽然它与subgrid不同,但在某些情况下可以起到类似的作用。
<div class="grid-parent">
<div class="grid-item"></div>
<div class="grid-item"></div>
<ul style="display: contents;">
<!-- These grid-items get to participate on
the same grid!-->
<li class="grid-item"></li>
<li class="grid-item"></li>
</ul>
</div>
Grid Container属性
display:grid
.container {
display: grid | inline-grid;
}
可以设置最外层的Container为Grid布局或者行内Grid布局;
grid-template-columns & grid-template-rows
使用以空格分隔的值来定义网格的列和行。这些值表示轨道大小,它们之间的空间表示网格线。
值:
<track-size> – 可以是长度、百分比或使用fr单位表示的网格中可用空闲空间的分数(有关该单位的更多信息,请参考DigitalOcean)
<line-name> – 您选择的任意名称
比如:
.container {
grid-template-columns: ... ...;
/* e.g.
1fr 1fr
minmax(10px, 1fr) 3fr
repeat(5, 1fr)
50px auto 100px 1fr
*/
grid-template-rows: ... ...;
/* e.g.
min-content 1fr min-content
100px 1fr max-content
*/
}
网格线会根据这些分配自动被赋予正数(-1代表最后一行的替代)。
但是您也可以选择显式地为网格线命名。请注意,使用方括号来表示线的名称:
.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];
}
具有用户命名线的网格 请注意,一条线可以有多个名称。例如,这里的第二行将有两个名称: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]);
}
这等效于:
.container {
grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start];
}
如果多个线共享相同的名称,可以通过它们的线名称和计数来引用它们。
.item {
grid-column-start: col-start 2;
}
fr单位允许您将轨道的大小设置为网格容器的可用空闲空间的一部分。例如,这将使每个项的宽度为网格容器宽度的三分之一:
.container {
grid-template-columns: 1fr 1fr 1fr;
}
可用空闲空间是在任何非灵活项之后计算的。在这个例子中,fr单位的可用总空间不包括50px:
.container {
grid-template-columns: 1fr 50px 1fr 1fr;
}
grid-template-areas
通过引用使用grid-area属性指定的网格区域的名称来定义网格模板。重复网格区域的名称会导致内容跨越这些单元格。句点(.)表示空单元格。语法本身提供了网格结构的可视化。
值:
<grid-area-name> - 使用grid-area指定的网格区域的名称
. - 句点表示空的网格单元格
none - 没有定义网格区域
示例:
.item-a {
grid-area: header;
}
.item-b {
grid-area: main;
}
.item-c {
grid-area: sidebar;
}
.item-d {
grid-area: footer;
}
.container {
display: grid;
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";
}
这将创建一个由四列宽度和三行高度组成的网格。整个顶行将由标题区域组成。中间行将由两个主要区域、一个空单元格和一个侧边栏区域组成。最后一行则全部是页脚。
您的声明中的每一行都需要具有相同数量的单元格。
您可以使用任意数量的相邻句点来声明一个空单元格。只要句点之间没有空格,它们就代表一个单元格。
请注意,使用此语法时,并未为行线命名,只为区域命名。使用此语法时,实际上会自动为区域两端的线条命名。如果您的网格区域名为foo,那么该区域起始行线和起始列线的名称将是foo-start,而最后一行线和最后一列线的名称将是foo-end。这意味着某些线可能具有多个名称,例如上述示例中的最左侧线将有三个名称:header-start、main-start和footer-start。
grid-template
一种用于在单个声明中设置grid-template-rows、grid-template-columns和grid-template-areas的简写方式。
取值:
none - 将三个属性都设置为初始值。
<grid-template-rows> / <grid-template-columns> - 分别将grid-template-columns和grid-template-rows设置为指定的值,并将grid-template-areas设置为none。
语法示例:
.container {
grid-template: none | <grid-template-rows> / <grid-template-columns>;
}
它还接受一种更复杂但非常方便的语法来指定这三个属性。以下是一个示例:
.container {
grid-template:
[row1-start] "header header header" 25px [row1-end]
[row2-start] "footer footer footer" 25px [row2-end]
/ auto 50px auto;
}
这等同于以下写法:
.container {
grid-template-rows: [row1-start] 25px [row1-end row2-start] 25px [row2-end];
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。
gap相关
column-gap & row-gap & grid-column-gap & grid-row-gap
指定网格线的大小。您可以将其视为设置列/行之间间距的宽度。
取值:
<line-size> - 一个长度值。
语法示例:
.container {
/* standard */
column-gap: <line-size>;
row-gap: <line-size>;
/* old */
grid-column-gap: <line-size>;
grid-row-gap: <line-size>;
}
示例:
.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
column-gap: 10px;
row-gap: 15px;
}
这些间距只会在列/行之间创建,而不会出现在外部边缘。
注意:grid-前缀将被移除,并且grid-column-gap和grid-row-gap将更名为column-gap和row-gap。未加前缀的属性已在Chrome 68+、Safari 11.2 Release 50+和Opera 54+中得到支持。
gap & grid-gap
row-gap和column-gap的简写形式
取值:
<grid-row-gap> <grid-column-gap> - 长度值
语法示例:
.container {
/* standard */
gap: <grid-row-gap> <grid-column-gap>;
/* old */
grid-gap: <grid-row-gap> <grid-column-gap>;
}
示例:
.container {
grid-template-columns: 100px 50px 100px;
grid-template-rows: 80px auto 80px;
gap: 15px 10px;
}
如果未指定row-gap,则将其设置为与column-gap相同的值。
注意:grid-前缀已被弃用(但是谁知道,可能实际上从浏览器中永远不会删除)。实际上,grid-gap被重命名为gap。未加前缀的属性已在Chrome 68+、Safari 11.2 Release 50+和Opera 54+中得到支持。
内容布局相关
justify-items
在网格布局中,该属性用于沿行内轴(与 align-items 属性沿列轴对齐的方式相对)对齐网格项。此值适用于容器内的所有网格项。
取值:
start – 将项目与其单元格的起始边对齐
end – 将项目与其单元格的结束边对齐
center – 将项目居中对齐于其单元格
stretch – 撑满整个单元格的宽度(默认值)
container {
justify-items: start | end | center | stretch;
}
Examples:
.container {
justify-items: start;
}
.container {
justify-items: end;
}
.container {
justify-items: center;
}
.container {
justify-items: stretch;
}
这种行为也可以通过 justify-self 属性在单个网格项上进行设置。
align-items
该属性用于沿块轴(与 justify-items 属性沿行内轴对齐的方式相对)对齐网格项。此值适用于容器内的所有网格项。
取值:
stretch – 撑满整个单元格的高度(默认值)
start – 将项目与其单元格的起始边对齐
end – 将项目与其单元格的结束边对齐
center – 将项目居中对齐于其单元格
baseline – 将项目沿文本基线对齐。对于多行文本,可以使用 first baseline 和 last baseline 修饰符,将使用第一行或最后一行的基线。
.container {
align-items: start | end | center | stretch;
}
Examples:
.container {
align-items: start;
}
.container {
align-items: end;
}
.container {
align-items: center;
}
.container {
align-items: stretch;
}
这种行为也可以通过 align-self 属性在单个网格项上进行设置。
此外,还有修饰关键字 safe 和 unsafe(使用方式类似于 align-items: safe end)。safe 关键字表示“尝试按照指定方式对齐,但不要导致项目移动到不可访问的溢出区域”,而 unsafe 则允许将内容移动到不可访问的区域(可能会导致数据丢失)。
place-items
place-items 属性可以在一次声明中同时设置 align-items 和 justify-items 属性。
取值:
<align-items> / <justify-items> – 第一个值设置 `align-items`,第二个值设置 `justify-items`。如果省略第二个值,则将第一个值分配给两个属性。
更多详情,请参阅 align-items 和 justify-items。
这在快速进行多方向居中对齐时非常有用:
.center {
display: grid;
place-items: center;
}
justify-content
有时候,网格的总尺寸可能小于其网格容器的尺寸。这可能发生在所有网格项都使用像像素(px)这样的非灵活单位进行尺寸设置的情况下。在这种情况下,您可以设置网格在网格容器内的对齐方式。该属性将网格沿行内轴对齐(与 align-content 属性沿列轴对齐的方式相对)。
取值:
start – 将网格与网格容器的起始边对齐
end – 将网格与网格容器的结束边对齐
center – 将网格居中对齐于网格容器
stretch – 调整网格项的大小,使网格填满网格容器的整个宽度
space-around – 在每个网格项之间均匀分布一定量的空白,两端空白的大小为中间空白的一半
space-between – 在每个网格项之间均匀分布一定量的空白,两端没有空白
space-evenly – 在每个网格项之间(包括两端)均匀分布一定量的空白
.container {
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
Examples:
.container {
justify-content: start;
}
.container {
justify-content: end;
}
.container {
justify-content: center;
}
.container {
justify-content: stretch;
}
.container {
justify-content: space-around;
}
.container {
justify-content: space-between;
}
.container {
justify-content: space-evenly;
}
align-content
有时候,您的网格的总尺寸可能小于其网格容器的尺寸。这可能发生在所有网格项都使用非灵活单位(如像素px)进行尺寸设置的情况下。在这种情况下,您可以设置网格在网格容器内的对齐方式。此属性沿块轴(与 justify-content 属性沿行内轴对齐的方式相对)对齐网格。
取值:
start – 将网格与网格容器的起始边对齐
end – 将网格与网格容器的结束边对齐
center – 将网格居中对齐于网格容器
stretch – 调整网格项的大小,使网格填满网格容器的整个高度
space-around – 在每个网格项之间均匀分布一定量的空白,两端空白的大小为中间空白的一半
space-between – 在每个网格项之间均匀分布一定量的空白,两端没有空白
space-evenly – 在每个网格项之间(包括两端)均匀分布一定量的空白
.container {
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
示例:
.container {
align-content: start;
}
.container {
align-content: end;
}
.container {
align-content: center;
}
.container {
align-content: stretch;
}
.container {
align-content: space-around;
}
.container {
align-content: space-between;
}
.container {
align-content: space-evenly;
}
place-content
place-content 属性可以在一次声明中同时设置 align-content 和 justify-content 属性。
取值:
<align-content> / <justify-content> – 第一个值设置 align-content,第二个值设置 justify-content。如果省略第二个值,则将第一个值分配给两个属性。
除了 Edge 浏览器外,所有主要浏览器都支持 place-content 简写属性。
更多详情,请参阅 align-content 和 justify-content。
Grid Item属性
grid-column-start & grid-column-end & grid-row-start & grid-row-end
通过参考特定的网格线,确定网格项在网格中的位置。grid-column-start/grid-row-start表示项开始的线,而grid-column-end/grid-row-end表示项结束的线。
数值:
<line> - 可以是一个数字,表示一个编号的网格线,或者是一个名称,表示一个命名的网格线。
span <number> - 项将横跨提供的网格轨道数量。
span <name> - 项将横跨直到下一个具有提供的名称的线。
auto - 表示自动布局,自动跨度,或默认跨度为1。
语法示例:
.item {
grid-column-start: <number> | <name> | span <number> | span <name> | auto;
grid-column-end: <number> | <name> | span <number> | span <name> | auto;
grid-row-start: <number> | <name> | span <number> | span <name> | auto;
grid-row-end: <number> | <name> | span <number> | span <name> | auto;
}
示例:
.item-a {
grid-column-start: 2;
grid-column-end: five;
grid-row-start: row1-start;
grid-row-end: 3;
}
.item-b {
grid-column-start: 1;
grid-column-end: span col4-start;
grid-row-start: 2;
grid-row-end: span 2;
}
如果没有声明grid-column-end/grid-row-end,项将默认跨越1个网格轨道,参考链接。
项可以相互重叠,可以使用z-index来控制它们的堆叠顺序。
grid-column & grid-row
grid-column是如下2个属性的简写:grid-column-start & grid-column-end
grid-row是如下2个属性的简写: grid-row-start & grid-row-end
数值:
<start-line> / <end-line> - 每个值接受与长手写版本相同的所有值,包括span。
语法示例:
.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;
}
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;
}
justify-self
以一种方式来给单元格内的网格项沿着行轴(与沿着列轴对齐的align-self相对)分配对齐方式。此值适用于单个单元格内的网格项。
取值:
start - 将网格项与单元格的起始边对齐
end - 将网格项与单元格的结束边对齐
center - 将网格项居中对齐于单元格中
stretch - 填充整个单元格的宽度(默认值)
.item {
justify-self: start | end | center | stretch;
}
示例:
.item-a {
justify-self: start;
}
.item-a {
justify-self: end;
}
.item-a {
justify-self: center;
}
.item-a {
justify-self: stretch;
}
要为网格中的所有项设置对齐方式,还可以通过justify-items属性在网格容器上设置此行为。
align-self
以一种方式将网格项沿着列轴(与沿着行轴对齐的justify-self相对)对齐于单元格内。此值适用于单个网格项内的内容。
取值:
start - 将网格项与单元格的起始边对齐
end - 将网格项与单元格的结束边对齐
center - 将网格项居中对齐于单元格中
stretch - 填充整个单元格的高度(默认值)
.item {
align-self: start | end | center | stretch;
}
Examples:
.item-a {
align-self: start;
}
.item-a {
align-self: end;
}
.item-a {
align-self: center;
}
.item-a {
align-self: stretch;
}
要对齐网格中的所有项,还可以通过align-items属性在网格容器上设置此行为。
place-self
place-self在单个声明中同时设置align-self和justify-self属性。
取值:
auto - 布局模式的“默认”对齐方式。
<align-self> / <justify-self> - 第一个值设置align-self,第二个值设置justify-self。如果省略第二个值,则将第一个值分配给两个属性。
语法示例:
.item-a {
place-self: center;
}
.item-a {
place-self: center stretch;
}
除了Edge浏览器外,所有主流浏览器都支持place-self简写属性。
浏览器支持情况
Desktop
| Chrome | Firefox | IE | Edge | Safari |
|---|---|---|---|---|
| 57 | 52 | 11* | 16 | 10.1 |
Mobile / Tablet
| Android Chrome | Android Firefox | Android | iOS Safari |
|---|---|---|---|
| 114 | 113 | 114 | 10.3 |
流式列代码片段
下面是一个用于创建流式列的CSS代码片段:
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
}
这个代码片段将一个包含列的容器元素定义为网格布局。grid-template-columns属性设置了列的大小和数量。在这个例子中,我们使用repeat(auto-fit, minmax(200px, 1fr))来创建自适应的列。它的意思是列的宽度将自动适应容器的大小,并且每列的最小宽度为200像素,最大宽度为1个单位。这使得列可以自动调整大小以填充容器。
gap属性定义了列之间的间隔,这里设置为20像素。您可以根据需要调整这个值。
您可以将这段代码应用于适当的HTML元素,以创建流式列布局。
CSS Grid动画
根据CSS Grid布局模块一级规范,有五个可动画化的网格属性:
- grid-gap、grid-row-gap、grid-column-gap可以使用长度、百分比或calc作为值。
- grid-template-columns、grid-template-rows可以作为简单的长度、百分比或calc组成的列表,只要列表中的长度、百分比或calc组件的值有所不同即可。
截至目前,已经有一些经过测试的浏览器支持对(grid-)gap、(grid-)row-gap和(grid-)column-gap进行动画化处理。
| Browser | (grid-)gap, (grid-)row-gap, (grid-)column-gap | grid-template-columns | grid-template-rows |
|---|---|---|---|
| Firefox | supported ✅ 53+ | supported ✅ 66+ | supported ✅ 66+ |
| Safari 12.0 | not supported ❌ | not supported ❌ | not supported ❌ |
| Chrome | supported ✅ 66+ | not supported ❌ | not supported ❌ |
| Chrome for Android 66+, Opera Mini 33+ | supported ✅ | not supported ❌ | not supported ❌ |
| Edge | supported ✅ 16+ | not supported ❌ | not supported ❌ |
示例:
<p>Check <a href="https://www.matuzo.at/blog/2023/100daysof-day97/">this post</a> for more details</p>
<button class="js-button">Animate</button>
<div class="grid js-grid">
<div class="item">
<h2>Element 1</h2>
</div>
<div class="item">
<h2>Element 2</h2>
</div>
<div class="item">
<h2>Element 3</h2>
</div>
<div class="item">
<h2>Element 4</h2>
</div>
<div class="item">
<h2>Element 5</h2>
</div>
<div class="item">
<h2>Element 6</h2>
</div>
<div class="item">
<h2>Element 7</h2>
</div>
<div class="item">
<h2>Element 8</h2>
</div>
<div class="item">
<h2>Element 9</h2>
</div>
<div class="item">
<h2>Element 10</h2>
</div>
<div class="item">
<h2>Element 11</h2>
</div>
<div class="item">
<h2>Element 12</h2>
</div>
</div>
Css:
button {
background-color: #123456;
color: #ffffff;
margin: 2rem 0;
padding: 1.4rem;
border: none;
border-radius: 5px;
text-transform: uppercase;
font-size: 1.2rem;
}
button:focus-visible {
outline: 4px solid #123456;
outline-offset: 4px;
}
dt {
font-weight: bold;
margin-bottom: 0.5rem;
}
Js:
document.querySelector('.js-button').addEventListener('click', function() {
document.querySelector('.js-grid').classList.toggle('grid--full')
})