发布于 2026-01-06 4 阅读
0

CSS Grid Areas 非常棒!轨道和线条区域的响应式和语义总结。DEV 的全球展示挑战赛,由 Mux 呈现:展示你的项目!

CSS Grid Areas 太棒了

轨道和线路

区域

响应性和语义

结论

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

当我第一次了解到 CSS Grid 布局以及它赋予我们 CSS 开发者的强大功能时,我立刻兴奋不已。想到可以摆脱divBootstrap 或 Foundation 网格布局中那些层层非语义化的容器,用纯粹语义化的 HTML 文档取而代之,并将布局完全交给 CSS 来处理——这才是布局应有的样子——我就激动不已。

但当我与其他对语义化标记不太热衷的开发者交流时,我经常得到的回复是:“我已经知道如何用网格系统了,我现在真的不想学习新的东西……我真的能从中获得一些实用的东西吗?还是最终只是换了个地方回到原点?CSS Grid 能做到哪些基本网格系统做不到的事情?

今天我想用两个词来回答这个问题:网格区域

轨道和线路

在 CSS 网格布局中,网格由轨道线条构成。“轨道”是行或列的通用术语。顾名思义,“线条”是轨道之间的边界。我们使用 `<track>` 和 `<line>` 来定义网格的轨道grid-template-rows,然后使用 `<line>` 和`<line>`grid-template-columns将网格项添加到线条上grid-rowgrid-column

网格轨道和线路

很多情况下,或许大多数情况下,你只需要轨道和线条就能定义网格。尤其对于包含动态内容的较小区域,例如搜索结果网格或好友列表网格,你通常只需使用grid-template-columns轨道和线条来定义列,使用grid-auto-rows线条来声明新行的高度,然后让 CSS Grid 出色的自动填充功能为你填充网格即可。

但有时情况并非如此灵活。有时,你需要预先定义好一组固定的元素,并将它们放置在网格中。你清楚地知道它们应该放在哪里,只想让浏览器正确识别元​​素,不需要任何自动放置的技巧。这种情况在使用网格布局网站的顶层结构时非常常见:页眉放在这里,导航栏放在这里,头像放在那里,内容放在这里,就完成了。

你当然仍然可以通过将轨道固定块与行号关联来定义所有内容,这非常常见。例如,假设你要编写一个简单的用户个人资料,其中包含四个部分:显示名称、头像、“关于”部分以及用户发布的帖子列表。你可以这样做:



<main>
  <h1 class="display-name">...</h1>
  <section class="avatar"><img src="..."></section>
  <section class="about">...</section>
  <section class="posts">...</section>
</main>


Enter fullscreen mode Exit fullscreen mode


main {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
}
.display-name {
  grid-row: 1 / 2;
  grid-column: 3 / 6;
}
.avatar {
  grid-row: 1 / 3;
  grid-column: 1 / 3;
}
.about {
  grid-row: 3 / 4;
  grid-column: 1 / 3;
}
.posts {
  grid-row: 2 / 5;
  grid-column: 3 / 6;
}


Enter fullscreen mode Exit fullscreen mode

grid-template-columns网格容器的规则定义了我们的列轨道,而网格项的grid-row规则grid-column指定了哪些网格线应该作为每个项的边界。

这确实有效。但这里也存在一些令人沮丧的问题:

  • 盯着一堆数字看会让你的网格布局难以理解,我经常需要反复调整行号才能让布局看起来合理。这并非 CSS Grid 特有的问题,而且说实话,它比调整内边距、外边距和浮动值要容易得多flex-grow,但仍然值得一提。
  • 如果我之后想在现有轨道或项目之间添加新的轨道或项目怎么办?我可能需要更新上面很多行号。你可以使用关键字span而不是固定的行号来设置列和行的结束值,这样你就可以指定要覆盖多少轨道,而不是在哪条网格线上停止,但这有利有弊;有时有用,有时反而会造成干扰。
  • 上面有很多重复的内容。与前一点相关,如果你只是想在左侧添加一列,比如侧边栏,你就必须找到所有出现的 ` grid-row: 1 / ...1` 并将其更新为 `2`。在更复杂的布局中,这种​​情况会更加严重。
  • 使用媒体查询断点来改变布局的响应式布局可能会有点冗长和令人困惑,因为你需要为每个断点指定所有这些值,这在某种程度上加剧了可视化每个不同布局的问题。

值得庆幸的是,CSS Grid 规范的编写者们为我们提供了一个很棒的功能,可以帮助解决所有这些问题:网格区域!

区域

网格区域是网格的矩形部分,每边都由网格线界定(因此有 4 条网格线,2 条水平线和 2 条垂直线)。

使用此功能最简单(也最无趣)的方式是将其作为网格项中行和列的简写形式。上面示例中的每个部分都可以简化为一条grid-area规则:



/*
 grid-area: row-start / col-start / row-end / col-end;
*/

.about {
  grid-area: 3 / 1 / 5 / 3;
}


Enter fullscreen mode Exit fullscreen mode

但这并没有真正解决我列出的任何问题;事实上,你可能会认为情况更糟,因为它更难读懂。(哪个数字代表什么grid-row-end来着?)

所以,与其展示这些轨道和线条,不如让我向你展示一个当初让我惊叹不已的 CSS Grid 功能:grid-template-areas



main {
  display: grid;
  grid-template-areas: 
    "avatar avatar  name  name  name"
    "avatar avatar  posts posts posts"
    "about  about   posts posts posts"
    ".      .       posts posts posts"
  ;
}
.display-name {
  grid-area: name;
}
.avatar {
  grid-area: avatar;
}
.about {
  grid-area: about;
}
.posts {
  grid-area: posts;
}


Enter fullscreen mode Exit fullscreen mode

瞧瞧。

正确的?

正确的???

我们没有定义行和列,而是用命名网格区域的方式直观地布局了整个网格,采用了瑞秋·安德鲁所说的“ASCII艺术”方法来描述网格。每一行都用双引号(“...”)括起来的字符串表示,每个单元格都标有它所属的网格区域的名称。如果某个单元格不需要属于任何区域,只需在该位置放置一个点(或多个点,取决于个人风格)。单元格之间用空格分隔,多余的空格会被折叠,这使得网格的视觉格式化变得非常容易。

每个网格区域由所有与其名称相同的单元格定义。正如你可能猜到的,你的区域必须是矩形连续的;这里不允许出现俄罗斯方块或虫洞。

定义好网格区域后,就可以通过将网格项的grid-area规则设置为要放置网格项的区域名称,将网格项附加到这些区域上!

注意这里没有grid-template-columns`or`grid-template-rows参数;默认情况下,轨道大小直接从 ASCII 图形推断得出!(是不是很酷??)话虽如此,你仍然可以根据需要使用这些规则;这在调整尺寸时通常是必要的。你也可以使用简写规则grid-template一次性定义所有三个规则。在这个简写规则中,你可以选择在每行描述后立即为其指定高度,然后,如果你想要设置列宽,可以在最后一行后添加一个斜杠,并在末尾指定列宽:



grid-template:
  "avatar avatar  name  name  name"   2rem
  "avatar avatar  posts posts posts"
  "about  about   posts posts posts"  6rem
  "...... ......  posts posts posts"
  / 2fr    10px    3fr   1fr   5vw
;


Enter fullscreen mode Exit fullscreen mode

依我看来,对于包含静态项目的网格布局来说,这种方式比冗长的显式网格线列表要易读、可视,并且最终更易于维护。

响应性和语义

如果有人问我,CSS Grid 最令人兴奋的地方是什么,我会这样回答:CSS Grid 为 Web 带来的最大好处是,它可以轻松实现响应式设计,而不会牺牲语义。

在上面的用户个人资料示例中,细心的读者可能已经注意到一些奇怪之处:在 HTML 代码中,各个部分的顺序是:

  • 显示名称
  • 头像
  • 关于
  • 帖子

但在网格布局中,头像排在最前面,右侧是显示名称,下方是“关于”部分,右下角是文章。此外,“文章”部分在垂直方向上与头像和“关于”部分重叠。

关键在于:HTML 标签的编写顺序符合语义逻辑,而网格布局则符合视觉逻辑。HTML 的编写顺序与我希望用户阅读信息的顺序一致。这一点对于使用辅助技术(例如屏幕阅读器)的用户尤为重要:CSS 在视觉上调整页面元素的顺序不会影响元素的实际顺序,因此语义逻辑得以保留。

以上涵盖了语义方面的内容,那么响应式设计又是怎么回事呢?不妨设想一下,如果用户将我们的个人资料布局缩小到移动设备尺寸,特别是小屏幕上的竖屏显示,会发生什么情况。(也许您已经在用移动设备阅读这篇文章了,所以您不必想象!)效果肯定不理想。因此,让我们添加一个媒体查询断点,比如在某个位置,800px来重新排列布局,使其与上面列出的部分顺序相符。准备好了吗?以下是代码:



@media(max-width: 800px) {
  main {
    grid-template-areas:
        "name"
        "avatar"
        "about"
        "posts"
    ;
  }
}


Enter fullscreen mode Exit fullscreen mode

砰!就这么简单。就这么简单。

它的视觉效果和第一个布局一样好。如果你想要第三种布局,比如一个适用于超宽屏幕、略显夸张,并将头像移到左侧第三列的布局,那也很容易做到:



@media(min-width: 1500px) {
  main {
    grid-template-areas:
        "avatar name  posts"
        "avatar about posts"
        ".      .     posts"
    ;
  }
}


Enter fullscreen mode Exit fullscreen mode

这里有一个演示,包含了上面提到的所有三种布局,但使用了grid简写规则,该规则会重置轨道尺寸等值。这样可以避免默认布局中的轨道尺寸被其他布局继承,从而避免出现问题,而无需我在每个断点处显式地覆盖这些值。

注意:您可以使用 codepen 小部件下方的“1x”、“0.5x”和“0.25x”按钮来查看三种不同的布局。

在这三种布局中,HTML 源代码的顺序始终保持不变,因此使用屏幕阅读器阅读的用户,或者使用网络爬虫或屏幕抓取工具的用户,仍然能够以首选的语义顺序获取页面上的信息。

结论

我希望你能同意我的观点。我仍然听到一些尚未认真研究过 CSS Grid 的 Web 开发人员的抵触情绪,他们认为他们不想学习新东西,认为它基本上与他们已经了解和使用的基于浮动或 Flexbox 的网格系统相同,或者,最离谱的是,认为它只是回到了基于表格的布局

我希望这篇文章已经展示了 CSS Grid 的强大之处,无论是在它可以生成的布局方面,还是在创建和维护灵活、响应式、美观的布局方面,而且这一切都不会牺牲结构良好、简洁、语义纯正的 HTML。

我再次要大力赞扬瑞秋·安德鲁 (Rachel Andrew)。如果你还不知道她的网站gridbyexample.com,一定要去看看。她十年来一直致力于推广 CSS Grid,而且她和珍·西蒙斯(Jen Simmons) 一起,通过她们的视频和教程教会了我如何使用 Grid。最后,我想请瑞秋来总结一下:

文章来源:https://dev.to/kenbellows/css-grid-areas-are-amazing-1gha