CSS 网格简介
CSS 网格布局(也称为“网格”或“CSS 网格”)是一个二维基于网格的布局系统,与过去任何 Web 布局系统相比,它彻底改变了我们设计用户界面的方式。CSS 一直用于布局我们的网页,但它从未做得很好。首先,我们使用表格,然后使用浮动、定位和内联块,但所有这些方法本质上都是黑客,并且遗漏了许多重要的功能(例如垂直居中)。Flexbox 也是一个非常棒的布局工具,但它单向流动具有不同的用例 — 它们实际上协同工作得很好!网格是第一个专门为了解决我们一直以来在制作网站时一直以黑客方式解决的布局问题而创建的 CSS 模块。
本指南的目的是介绍网格概念,因为它们存在于规范的最新版本中。因此,我不会介绍过时的 Internet Explorer 语法(尽管您可以绝对在 IE 11 中使用网格)或其他历史黑客。
CSS 网格基础
截至 2017 年 3 月,大多数浏览器都发布了对 CSS 网格的原生、未带前缀的支持:Chrome(包括 Android)、Firefox、Safari(包括 iOS)和 Opera。另一方面,Internet Explorer 10 和 11 支持它,但它是一个旧的实现,具有过时的语法。现在是使用网格构建的时候了!
要开始,您必须使用 display: grid
定义一个容器元素作为网格,使用 grid-template-columns
和 grid-template-rows
设置列和行大小,然后使用 grid-column
和 grid-row
将子元素放置到网格中。与 flexbox 类似,网格项目的源顺序无关紧要。您的 CSS 可以按任何顺序放置它们,这使得使用媒体查询重新排列网格变得超级容易。想象一下,定义整个页面的布局,然后仅用几行 CSS 就完全重新排列它以适应不同的屏幕宽度。网格是有史以来引入的最强大的 CSS 模块之一。
重要的 CSS 网格术语
在深入研究网格概念之前,了解术语非常重要。由于此处涉及的术语在概念上都比较相似,因此如果您没有先记住网格规范定义的含义,就很容易将它们混淆。但不用担心,它们并不多。
网格容器
应用了 display: grid
的元素。它是所有网格项目的直接父级。在本例中, container
是网格容器。
<div class="container">
<div class="item item-1"> </div>
<div class="item item-2"> </div>
<div class="item item-3"> </div>
</div>
网格线
构成网格结构的分割线。它们可以是垂直的(“列网格线”)或水平的(“行网格线”),并且位于行或列的任一侧。这里黄色线是列网格线的示例。
网格轨道
两个相邻网格线之间的空间。你可以把它想象成网格的列或行。这是第二行和第三行网格线之间的网格轨道。
网格区域
由四条网格线包围的总空间。一个网格区域可以包含任意数量的网格单元。这里是第一行和第三行网格线之间,以及第一列和第三列网格线之间的网格区域。
CSS 网格属性
(网格容器)
父元素的属性跳转链接
display
将元素定义为网格容器,并为其内容建立新的网格格式化上下文。
值
grid
– 生成块级网格inline-grid
– 生成行内级网格
.container {
display: grid | inline-grid;
}
将网格参数向下传递给嵌套元素(又称子网格)的能力已移至 CSS 网格规范的第 2 级。 这里有一个 快速说明.
grid-template-rows
grid-template-columns使用用空格分隔的值列表定义网格的列和行。这些值表示轨道大小,它们之间的空格表示网格线。
值
<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
– 未定义任何网格区域。
.container {
grid-template-areas:
"<grid-area-name> | . | 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";
}
这将创建一个宽度为四列,高度为三行的网格。整个顶行将由 header 区域组成。中间行将由两个 main 区域,一个空单元格和一个 sidebar 区域组成。最后一行全部是 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
。
row-gap
grid-column-gap
grid-row-gap
column-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+ 已支持无前缀属性。
grid-gap
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;
}
示例
.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
– 将项目对齐到文本基线。baseline
有两个修饰符:first baseline
和last baseline
,在多行文本情况下,它们将使用第一行或最后一行文本的基线进行对齐。
.container {
align-items: start | end | center | stretch;
}
示例
.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;
}
示例
.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-auto-rows
grid-auto-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;
}
这将创建一个 2 x 2 的网格。
但是现在假设使用 grid-column
和 grid-row
像这样定位网格项目:
.item-a {
grid-column: 1 / 2;
grid-row: 2 / 3;
}
.item-b {
grid-column: 5 / 6;
grid-row: 2 / 3;
}
我们告诉 .item-b 从第 5 列线开始,到第 6 列线结束, 但我们从未定义过第 5 列线或第 6 列线。因为我们引用了不存在的行,所以会创建宽度为 0 的隐式轨道来填补间隙。可以使用 grid-auto-columns
和 grid-auto-rows
指定这些隐式轨道的宽度。
.container {
grid-auto-columns: 60px;
}
grid-auto-flow
如果您的网格项目没有在网格上明确放置,则 _自动放置算法_ 会启动以自动放置项目。 此属性控制自动放置算法的工作方式。
值
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>
您定义了一个具有五列两行的网格,并将 grid-auto-flow
设置为 row
(这也是默认值)
.container {
display: grid;
grid-template-columns: 60px 60px 60px 60px 60px;
grid-template-rows: 30px 30px;
grid-auto-flow: row;
}
在网格上放置项目时,您只指定了其中两个项目的位置
.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)如何在可用行中流动
如果我们将 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;
}
grid
在单个声明中设置以下所有属性的简写形式:grid-template-rows
、grid-template-columns
、grid-template-areas
、grid-auto-rows
、grid-auto-columns
和 grid-auto-flow
(注意:您只能在单个网格声明中指定显式或隐式网格属性)。
值
none
– 将所有子属性设置为其初始值。<grid-template>
– 与grid-template
简写形式的工作方式相同。<grid-template-rows> / [ auto-flow && dense? ] <grid-auto-columns>?
– 将grid-template-rows
设置为指定的值。 如果斜杠右侧是auto-flow
关键字,则将grid-auto-flow
设置为column
。 如果还指定了dense
关键字,则自动放置算法使用“密集”打包算法。 如果省略了grid-auto-columns
,则将其设置为auto
。[ auto-flow && dense? ] <grid-auto-rows>? / <grid-template-columns>
– 将grid-template-columns
设置为指定的值。 如果斜杠左侧是auto-flow
关键字,则将grid-auto-flow
设置为row
。 如果还指定了dense
关键字,则自动放置算法使用“密集”打包算法。 如果省略了grid-auto-rows
,则将其设置为auto
。
示例
以下两个代码块是等效的
.container {
grid: 100px 300px / 3fr 1fr;
}
.container {
grid-template-rows: 100px 300px;
grid-template-columns: 3fr 1fr;
}
以下两个代码块是等效的
.container {
grid: auto-flow / 200px 1fr;
}
.container {
grid-auto-flow: row;
grid-template-columns: 200px 1fr;
}
以下两个代码块是等效的
.container {
grid: auto-flow dense 100px / 1fr 2fr;
}
.container {
grid-auto-flow: row dense;
grid-auto-rows: 100px;
grid-template-columns: 1fr 2fr;
}
以下两个代码块是等效的
.container {
grid: 100px 300px / auto-flow 200px;
}
.container {
grid-template-rows: 100px 300px;
grid-auto-flow: column;
grid-auto-columns: 200px;
}
它还接受一种更复杂但非常方便的语法来一次设置所有内容。 您指定 grid-template-areas
、grid-template-rows
和 grid-template-columns
,所有其他子属性都设置为其初始值。 您所做的是在线指定行名和轨道大小及其相应的网格区域。 最好用示例来描述这一点
.container {
grid: [row1-start] "header header header" 1fr [row1-end]
[row2-start] "footer footer footer" 25px [row2-end]
/ auto 50px auto;
}
等效于以下内容
.container {
grid-template-areas:
"header header header"
"footer footer footer";
grid-template-rows: [row1-start] 1fr [row1-end row2-start] 25px [row2-end];
grid-template-columns: auto 50px auto;
}
(Grid Items)
Properties for the Children跳转链接
float
、display: inline-block
、display: table-cell
、vertical-align
和 column-*
属性对网格项目没有影响。
grid-column-end
grid-row-start
grid-row-end
grid-column-start通过引用特定网格线来确定网格项目在网格中的位置。 grid-column-start
/grid-row-start
是项目开始的线,而 grid-column-end
/grid-row-end
是项目结束的线。
值
<line>
– 可以是数字,用于引用编号的网格线,也可以是名称,用于引用命名的网格线span <number>
– 项目将跨越提供的网格轨道数量span <name>
– 项目将跨越直到遇到带有指定名称的下一行auto
– 表示自动放置、自动跨越或默认跨越一个轨道
.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
来控制它们的堆叠顺序。
在 DigitalOcean 的这篇文章 中了解更多关于 span
符号的信息。
grid-row
grid-column分别是 grid-column-start
+ grid-column-end
和 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;
}
如果没有声明结束行值,则项目将默认跨越 1 个轨道。
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;
}
示例
.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
简写属性。
特殊单位和函数
fr 单位
您可能最终会在 CSS Grid 中使用很多 分数单位,例如 1fr
。它们本质上意味着“剩余空间的比例”。因此,像这样的声明
grid-template-columns: 1fr 3fr;
大致上表示 25% 75%
。但这些百分比值比分数单位要更加固定。例如,如果您为这些基于百分比的列添加了填充,那么您就破坏了 100% 的宽度(假设使用 content-box
盒模型)。分数单位也更便于与其他单位结合使用,正如您可以想象的那样。
grid-template-columns: 50px min-content 1fr;
尺寸关键字
在调整行和列大小的时候,您可以使用您习惯的所有 长度 单位,比如 px
、rem、% 等等,但您也可以使用关键字。
min-content
:内容的最小尺寸。想象一个像“E pluribus unum”这样的文本行,min-content
很有可能就是“pluribus”这个词的宽度。max-content
:内容的最大尺寸。想象上面那句话,max-content
就是整句话的长度。auto
:这个关键字很像fr
单位,除了它们在分配剩余空间时,在与fr
单位的尺寸争夺中“输掉”了。- 分数单位:参见上面
尺寸函数
fit-content()
函数使用可用空间,但绝不小于min-content
,也不大于max-content
。minmax()
函数的作用正如其名:它为长度的最小值和最大值设置了限制。这在与相对单位结合使用时很有用。例如,您可能希望一个列只能缩小到一定程度。这 非常有用,也可能正是您想要的
grid-template-columns: minmax(100px, 1fr) 3fr;
min()
函数。max()
函数。
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));
这两个关键字之间的区别 在这里详细说明。
Masonry
CSS Grid 的一项实验性功能是 Masonry 布局。请注意,有 很多方法可以实现 CSS Masonry 布局,但其中大多数都是技巧,要么有重大缺点,要么不是您期望的那样。
规范现在提供了一种官方方法,并且此方法在 Firefox 中需要一个标记。
.container {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: masonry;
}
查看 Rachel 的文章,了解更深入的探讨。
Subgrid
Subgrid 是 Grid 中一项非常有用的功能,它允许 Grid 项目拥有自己的 Grid,并且从父 Grid 继承 Grid 线。
.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>
CSS Grid 浏览器支持
这些浏览器支持数据来自 Caniuse,其中包含更多详细信息。数字表示浏览器从该版本及更高版本开始支持该功能。
桌面
Chrome | Firefox | IE | Edge | Safari |
---|---|---|---|---|
57 | 52 | 11* | 16 | 10.1 |
移动/平板
Android Chrome | Android Firefox | Android | iOS Safari |
---|---|---|---|
127 | 127 | 127 | 10.3 |
流畅列片段
流畅宽度列,根据可用空间自动分成更多或更少的列,无需使用媒体查询!
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* This is better for small screens, once min() is better supported */
/* grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr)); */
gap: 1rem;
}
CSS Grid 动画
根据 CSS Grid 布局模块级别 1 规范,有 5 个可动画的 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
的动画支持。
浏览器 | (grid-)gap 、(grid-)row-gap 、(grid-)column-gap | grid-template-columns | grid-template-rows |
---|---|---|---|
Firefox | 支持 ✅ 53+ | 支持 ✅ 66+ | 支持 ✅ 66+ |
Safari 12.0 | 不支持 ❌ | 不支持 ❌ | 不支持 ❌ |
Chrome | 支持 ✅ 66+ | 不支持 ❌ | 不支持 ❌ |
Chrome for Android 66+、Opera Mini 33+ | 支持 ✅ | 不支持 ❌ | 不支持 ❌ |
Edge | 支持 ✅ 16+ | 不支持 ❌ | 不支持 ❌ |
CSS 网格技巧!
用于大多数布局需求的 4 个 CSS 网格属性(以及一个值)
三行 CSS 代码实现日历
一种巧妙的固定页脚技巧
正方形中的徽标网格
轻量级砌体解决方案
CSS 网格中的手风琴行
不使用媒体查询的响应式网格布局
最小尺寸的自动填充 CSS 网格,具有最大列数
CSS 网格中的自动调整列大小:`auto-fill` 与 `auto-fit`
使用 CSS 网格进行布局
将 CSS 网格应用于 WordPress 布局
创建 CSS 网格叠加层
使用 CSS 网格创建会议时间表
使用 CSS 网格创建六边形网格
打破网格
CSS 网格和自定义形状,第一部分
为你的博客提供一些 CSS 网格小技巧
使用 CSS 计数器和 CSS 网格进行计数
使用 CSS 网格创建条形图
CSS 网格可以进行自动高度过渡
CSS 网格:一种布局,多种方式
CSS 网格入门布局
CSS 网格中等宽列有点奇怪
CSS 网格中的可扩展部分
探索 CSS 网格的隐式网格和自动放置功能
使用 CSS 网格像 Flexbox 一样将元素放在一行中
网格、内容重新排序和可访问性
隐式网格、可重复的布局模式和悬空元素
瞧,没有媒体查询!使用 CSS Grid 实现响应式布局
使用 CSS Grid 制作条形图
使用 CSS Grid 实现重叠标题
使用 CSS Grid 定位覆盖内容
防止 Grid 爆炸
简单命名的网格区域
使用 CSS Grid 和元素间边框线实现报纸版式
使用 CSS Grid 实现圣杯布局
使用 CSS Grid 搭配 position: sticky
学习 CSS Grid
CSS 网格布局的一些有趣事实
CSS `fr` 单位简介
CSS 网格中的自动调整列大小:`auto-fill` 与 `auto-fit`
CSS 居中指南
CSS 网格布局模块 Level 2
IE 中的 CSS 网格:CSS 网格和新的 Autoprefixer
CSS 网格是否取代了 Flexbox?
不要使用我的网格系统(或任何其他系统)
探索 CSS 网格的隐式网格和自动放置功能
`fit-content` 和 `fit-content()`
CSS 网格入门
Flexbox 和网格,你布局的最佳朋友
网格 Level 2 和 Subgrid
布局使用 Grid,组件使用 Flexbox
你好 Subgrid!
CSS float 过时了吗?
速度!Flexbox 和 Grid 之间有什么区别?
一些匹配设计稿的 CSS Grid 策略
Grid 的 dense 关键字的自动流动能力
显式网格和隐式网格的区别
关于 CSS Grid 布局,我学到的一些东西
用 CSS Grid 跳出思维定势
用 Grid 还是不用 Grid
使用 Grid 命名区域可视化(和引用)你的布局
为什么我们需要 CSS 子网格
CSS 网格视频
更多 CSS 网格资源
- CSS 网格布局模块级别 1 (W3C)
- 网格示例 (Rachel Andrew)
- 学习 CSS 网格布局 (Rachel Andrew)
- CSS 网格布局:简介 (DigitalOcean)
- CSS 网格布局:重复表示法 (DigitalOcean)
- CSS 网格布局:跨度关键字 (DigitalOcean)
- CSS 网格布局:Fr 单位 (DigitalOcean)
- CSS 网格:圣杯布局 (DigitalOcean)
- 如何使用 CSS 网格属性来对齐和排列内容和项目 (DigitalOcean)