CSS subgrid

发布时间:2023 年 9 月 28 日

CSS 网格是一款非常强大的布局引擎,但在父级网格上创建的行和列轨道只能用于定位网格容器的直接子项。除了直接子元素之外,任何其他元素上的任何作者定义的命名网格区域和线条都会丢失。借助 subgrid,轨道大小、模板和名称可以与嵌套网格共享。本文介绍了其运作方式。

子网格之前,内容通常需要手动调整,以避免出现像这样不整齐的布局。

三张卡片并排显示,每张卡片包含三部分内容:标题、段落和链接。每张卡片的文本长度各不相同,因此当它们并排显示时,会在卡片中造成一些不协调的对齐。

subgrid 之后,可以对大小可变的内容进行对齐。

三张卡片并排显示,每张卡片包含三部分内容:标题、段落和链接。每项文本的长度都不同,但子网格通过允许每项内容项中最高的项设置行高来修正了对齐方式,从而修正了所有对齐问题。

Browser Support

  • Chrome: 117.
  • Edge: 117.
  • Firefox: 71.
  • Safari: 16.

Source

子网格基础知识

下面是一个简单的用例,介绍了 CSS subgrid 的基础知识。网格由两个命名列定义,第一个列的宽度为 20ch,第二个列是空间 1fr 的“其余部分”。列名称不是必需的,但非常适合用于说明和教育目的。

.grid {
  display: grid;
  gap: 1rem;
  grid-template-columns: [column-1] 20ch [column-2] 1fr;
}

然后,将该网格的子项(跨越这两个列)设置为网格容器,并通过将 grid-template-columns 设置为 subgrid 来采用其父级的列。

.grid > .subgrid {
  grid-column: span 2;

  display: grid;
  grid-template-columns: subgrid; /* 20ch 1fr */
}
CSS 网格开发者工具的屏幕截图,显示了并排显示的两个列,列行开头有名称。
https://codepen.io/web-dot-dev/pen/NWezjXv

至此,父网格的列已有效传递到下一级子网格。现在,此子网格可以将子项分配给这两列中的任一列。

挑战!重复相同的演示,但针对 grid-template-rows 执行。

共享页面级“宏”网格

设计师通常使用共享网格,在整个设计上绘制线条,将他们想要的任何元素与其对齐。现在,Web 开发者也可以了!现在,您可以实现完全相同的工作流程,以及更多功能。

从宏观网格到完成的设计。 网格命名区域会预先创建,之后的组件会按需要放置。

实现最常见的设计师网格工作流程可以深入了解 subgrid 的功能、工作流程和潜力。

以下是从 Chrome DevTools 中截取的移动页面布局宏网格的屏幕截图。线条带有名称,并且有明确的组件放置区域。

Chrome CSS 网格开发者工具的屏幕截图,显示了移动设备大小的网格布局,其中行和列已命名以便快速识别:fullbleed、system-status、primary-nav、primary-header、main、footer 和 system-gestures。

以下 CSS 会创建此网格,并为设备布局提供命名的行和列。每行和每列都有大小。

.device {
    display: grid;
    grid-template-rows:
      [system-status] 3.5rem
      [primary-nav] 3rem
      [primary-header] 4rem
      [main] auto
      [footer] 4rem
      [system-gestures] 2rem
    ;
    grid-template-columns: [fullbleed-start] 1rem [main-start] auto [main-end] 1rem [fullbleed-end];
}

使用一些其他样式可获得以下设计。

与之前一样,CSS 开发者工具网格叠加层,但这次显示了一些移动系统界面、阴影和颜色。有助于了解设计的走向。

在此父元素内,包含各种嵌套元素。此设计要求在导航栏和标题行下方放置全宽图片。最左侧和最右侧的列线名称分别为 fullbleed-startfullbleed-end。通过这种方式命名网格线,可让子项同时根据 fullbleed放置简写对齐到各个网格线。您很快就会发现,这非常方便。

放大显示的 DevTools 网格叠加层屏幕截图,重点显示了 fullbleed-start 和 fullbleed-end 列名称。

使用命名良好的行和列创建总体设备布局后,使用 subgrid 将命名良好的行和列传递给嵌套网格布局。这就是 subgrid 神奇时刻。设备布局会将命名行和列传递给应用容器,然后容器会将其传递给其每个子项。

.device > .app,
.app > * {
    display: grid;
    grid: subgrid / subgrid;

    /* same as */
    grid-template-rows: subgrid;
    grid-template-columns: subgrid;
}

CSS 子网格是用于替代网格轨道列表的值。元素从其父级跨越的行和列现在与其提供的行和列相同。这样,.device 网格中的线条名称便可供 .app 的子项使用,而不仅仅是 .app.app 中的元素无法在子网格之前引用由 .device 创建的网格轨道。

定义完这些内容后,嵌套图片现在可以借助 subgrid 在布局中全局溢出。没有负值或技巧,而是一行代码就足以说明“我的布局从 fullbleed-start 延伸到 fullbleed-end”。

.app > main img {
    grid-area: fullbleed;
}
完成的宏布局,其中包含一个全宽嵌套图片,该图片位于主导航栏和标题行下方,并延伸到每个全出血命名列线。
https://codepen.io/web-dot-dev/pen/WNLyjzX

这样,您就得到了设计师使用的宏网格,它是用 CSS 实现的。此概念可根据需要扩展和发展。

检查支持情况

使用 CSS 和子网格进行渐进式增强非常简单易行。 使用 @supports,并在括号内询问浏览器是否将子网格视为模板列或行的值。以下示例检查 grid-template-columns 属性是否支持 subgrid 关键字,如果为 true,则表示可以使用子网格

@supports (grid-template-columns: subgrid) {
  /* safe to enhance to */
}

开发者工具

Chrome、Edge、Firefox 和 Safari 都提供了强大的 CSS 网格开发者工具,Chrome、Edge 和 Firefox 还提供了专门的工具来帮助处理子网格。Chrome 在 115 版中宣布了这些工具,而 Firefox 已经使用这些工具一年多了。

显示“元素”面板中元素上显示的子网格标记的屏幕截图预览。

子网格标记的运作方式与网格标记类似,但可直观区分哪些网格是子网格,哪些不是。

资源

此列表汇集了有关子网格的文章、演示和整体灵感,可帮助您轻松上手。如果您希望进一步了解子网格,欢迎探索这些实用资源!