使用命名网格线布局
在之前的指南中,我们已经了解了如何通过定义网格轨道创建的线来放置项目,以及如何使用命名模板区域来放置项目。在本指南中,我们将了解当我们使用命名线时,这两个方面如何协同工作。命名线非常有用,但一些更让人迷惑的网格语法来自这种命名和轨道大小的组合。一旦你完成了一些示例,它应该变得更清晰,更容易使用。
定义网格时命名行
在使用 grid-template-rows
和 grid-template-columns
属性定义网格时,可以为网格中的部分或所有线分配名称。为了演示,我将使用在基于行的放置指南中创建的简单布局。这次,我将使用命名线创建网格。
定义网格时,我在方括号内命名我的线。这些名称可以是任何你喜欢的。我为行和列的容器的开始和结束定义了一个名称。然后将网格的中心块再次定义为 content-start
和 content-end
,无论对于列还是行,尽管你并不需要为网格上的所有线命名。你可能选择只为布局中的一些关键线命名。
.wrapper {
display: grid;
grid-template-columns: [main-start] 1fr [content-start] 1fr [content-end] 1fr [main-end];
grid-template-rows: [main-start] 100px [content-start] 100px [content-end] 100px [main-end];
}
一旦线有了名称,我们就可以使用名称来放置项目,而不是使用行号。
.box1 {
grid-column-start: main-start;
grid-row-start: main-start;
grid-row-end: main-end;
}
.box2 {
grid-column-start: content-end;
grid-row-start: main-start;
grid-row-end: content-end;
}
.box3 {
grid-column-start: content-start;
grid-row-start: main-start;
}
.box4 {
grid-column-start: content-start;
grid-column-end: main-end;
grid-row-start: content-end;
}
<div class="wrapper">
<div class="box1">One</div>
<div class="box2">Two</div>
<div class="box3">Three</div>
<div class="box4">Four</div>
</div>
关于基于行的放置的所有其他内容仍然以相同的方式工作,并且可以混合使用命名线和行号。当创建响应式设计时,命名线非常有用,在这种设计中,你需要重新定义网格,而不是在媒体查询中通过更改行号来重新定义内容位置,你可以确保线在你的定义中始终具有相同的名称。
为线指定多个名称
你可能希望为一条线指定多个名称,例如,它可能表示边栏的结束和主区的开始。为此,在方括号内添加名称,并在它们之间用空格隔开 [sidebar-end main-start]
。然后,你可以使用这两个名称中的任何一个来引用该线。
从命名行生成隐式网格区域
在命名线时,我提到你可以使用任何你喜欢的名称。该名称是一个 自定义标识符,一个作者定义的名称。在选择名称时,你需要避免可能出现在规范中并引起混淆的词语 - 例如 span
。标识符不加引号。
虽然你可以选择任何名称,但如果你在某个区域周围的线后面添加 -start
和 -end
,就像我在上面的示例中所做的那样,网格将为你创建一个名为主要名称的命名区域。以上面的示例为例,我为行和列都设置了 content-start
和 content-end
。这意味着我将获得一个名为 content
的网格区域,如果需要,我可以将内容放置在该区域中。
我使用的是与上面相同的网格定义,但是这次我将把一个项目放置到名为 content
的命名区域中。
.wrapper {
display: grid;
grid-template-columns: [main-start] 1fr [content-start] 1fr [content-end] 1fr [main-end];
grid-template-rows: [main-start] 100px [content-start] 100px [content-end] 100px [main-end];
}
.thing {
grid-area: content;
}
<div class="wrapper">
<div class="thing">I am placed in an area named content.</div>
</div>
我们不需要使用 grid-template-areas
来定义区域在哪里,因为我们的命名线已经为我们创建了一个区域。
从命名区域生成隐式网格线
我们已经了解了命名线如何创建命名区域,反之亦然。命名模板区域会创建你可以用来放置项目的命名线。如果我们以网格模板区域指南中创建的布局为例,我们可以使用区域创建的线来查看它的工作原理。
在这个示例中,我添加了一个额外的 div,它有一个 overlay
类。我们使用 grid-area
属性创建了命名区域,然后使用 grid-template-areas
创建了布局。区域名称是
hd
ft
main
sd
这将为我们提供列和行线
hd-start
hd-end
sd-start
sd-end
main-start
main-end
ft-start
ft-end
您可以在图片中看到命名线,请注意,一些线具有两个名称 - 例如 sd-end
和 main-start
指的是同一列线。
使用这些隐式命名线来定位 overlay
与使用我们命名的线来定位项目相同。
.wrapper {
display: grid;
grid-template-columns: repeat(9, 1fr);
grid-auto-rows: minmax(100px, auto);
grid-template-areas:
"hd hd hd hd hd hd hd hd hd"
"sd sd sd main main main main main main"
"ft ft ft ft ft ft ft ft ft";
}
.header {
grid-area: hd;
}
.footer {
grid-area: ft;
}
.content {
grid-area: main;
}
.sidebar {
grid-area: sd;
}
.wrapper > div.overlay {
z-index: 10;
grid-column: main-start / main-end;
grid-row: hd-start / ft-end;
border: 4px solid rgb(92 148 13);
background-color: rgb(92 148 13 / 40%);
color: rgb(92 148 13);
font-size: 150%;
}
<div class="wrapper">
<div class="header">Header</div>
<div class="sidebar">Sidebar</div>
<div class="content">Content</div>
<div class="footer">Footer</div>
<div class="overlay">Overlay</div>
</div>
鉴于我们有这种从命名区域定位创建线和从命名线定位区域的能力,在开始创建网格布局时花点时间规划您的命名策略是值得的。通过选择对您和您的团队有意义的名称,您将帮助每个人更容易使用您创建的布局。
使用 repeat() 为多行使用相同名称
如果您想为网格中的所有线赋予唯一名称,那么您需要长写出轨道定义,而不是使用 repeat 语法,因为您需要在定义轨道时添加方括号中的名称。如果您使用 repeat 语法,您最终将得到多个具有相同名称的线,但这也很有用。
使用 repeat() 的十二列网格
在下一个示例中,我将创建一个具有十二个等宽列的网格。在定义列轨道的 1fr 大小之前,我还定义了一个名为 [col-start]
的线名。这意味着我们将得到一个网格,该网格在宽度为 1fr
的列之前有 12 个名为 col-start
的列线。
.wrapper {
display: grid;
grid-template-columns: repeat(12, [col-start] 1fr);
}
创建网格后,您可以将项目放置到其中。由于我们有多个名为 col-start
的线,如果您将项目放置到从线 col-start
开始的位置,网格将使用第一个名为 col-start
的线,在本例中是左边的线。要定位另一条线,请使用名称加该线的数字。要将我们的项目从第一个名为 col-start 的线放置到第 5 个线,我们可以使用
.item1 {
grid-column: col-start / col-start 5;
}
您也可以在这里使用 span
关键字。我的下一个项目将从第 7 个名为 col-start
的线开始,并跨越 3 个线。
.item2 {
grid-column: col-start 7 / span 3;
}
<div class="wrapper">
<div class="item1">I am placed from col-start line 1 to col-start 5</div>
<div class="item2">I am placed from col-start line 7 spanning 3 lines</div>
</div>
如果您在 Firefox 网格高亮显示器中查看此布局,您将看到如何显示列线以及如何将项目放置在这些线旁边。
使用轨道列表定义命名线
repeat 语法也可以接受轨道列表,它不只是重复单个轨道大小。下面的代码将创建一个具有八个轨道的网格,其中一个名为 col1-start
的更窄的 1fr
宽度列,后面是一个名为 col2-start
的更宽的 3fr
列。
.wrapper {
grid-template-columns: repeat(4, [col1-start] 1fr [col2-start] 3fr);
}
如果您的重复语法将两条线并排放置,那么它们将被合并,并创建与在非重复轨道定义中为线赋予多个名称相同的结果。以下定义创建了四个 1fr
轨道,每个轨道都有一个起始线和结束线。
.wrapper {
grid-template-columns: repeat(4, [col-start] 1fr [col-end]);
}
如果我们不使用 repeat 符号写出此定义,它将如下所示。
.wrapper {
grid-template-columns: [col-start] 1fr [col-end col-start] 1fr [col-end col-start] 1fr [col-end col-start] 1fr [col-end];
}
如果您使用了轨道列表,那么您可以使用 span
关键字不仅跨越一定数量的线,还可以跨越一定数量的特定名称的线。
.wrapper {
display: grid;
grid-template-columns: repeat(6, [col1-start] 1fr [col2-start] 3fr);
}
.item1 {
grid-column: col1-start / col2-start 2;
}
.item2 {
grid-row: 2;
grid-column: col1-start 2 / span 2 col1-start;
}
<div class="wrapper">
<div class="item1">
I am placed from col1-start line 1 to col2-start line 2
</div>
<div class="item2">
I am placed from col1-start line 2 spanning 2 lines named col1-start
</div>
</div>
十二列网格框架
在过去的三份指南中,您已经发现有很多不同的方法可以使用网格放置项目。这在最初看起来可能有点过于复杂,但请记住,您不必使用所有方法。在实践中,我发现对于简单的布局,使用命名模板区域效果很好,它提供了布局外观的良好视觉表示,然后可以轻松地在网格上移动项目。
如果使用严格的多列布局,例如本指南最后部分中命名线的演示效果很好。如果您考虑网格系统,例如在 Foundation 或 Bootstrap 等框架中找到的网格系统,这些网格系统基于 12 列网格。然后,框架导入代码以执行所有计算,以确保列加起来为 100%。对于网格布局,我们唯一的“框架”代码是
.wrapper {
display: grid;
gap: 10px;
grid-template-columns: repeat(12, [col-start] 1fr);
}
然后,我们可以使用该框架来布局我们的页面。例如,要创建一个带有标题和页脚的三列布局,我可能会有以下标记。
<div class="wrapper">
<header class="main-header">I am the header</header>
<aside class="side1">I am sidebar 1</aside>
<article class="content">I am the main article</article>
<aside class="side2">I am sidebar 2</aside>
<footer class="main-footer">I am the footer</footer>
</div>
然后,我可以将它放置在网格布局框架中,如下所示。
.main-header,
.main-footer {
grid-column: col-start / span 12;
}
.side1 {
grid-column: col-start / span 3;
grid-row: 2;
}
.content {
grid-column: col-start 4 / span 6;
grid-row: 2;
}
.side2 {
grid-column: col-start 10 / span 3;
grid-row: 2;
}
网格高亮显示器再次对我们很有帮助,它可以显示我们放置项目的网格的工作方式。
这就够了。我无需进行任何计算,网格会自动删除 10 像素的边距轨道,然后将空间分配给 1fr
列轨道。随着您开始构建自己的布局,您会发现语法变得更加熟悉,您会选择最适合您和您喜欢构建的项目类型的方式。尝试使用这些不同的方法构建一些常见模式,您很快就会找到最有效的工作方式。然后,在下一份指南中,我们将看看网格如何为我们定位项目,而无需我们使用任何放置属性!