网格

CSS 播客 - 011:网格

在网页设计中,一种非常常见的布局是页眉、边栏、正文和页脚布局。

带有徽标和导航的页眉,以及边栏和内容区域(用于重点介绍文章)

多年来, 有很多方法可以解决这种布局问题 但使用 CSS 网格 不仅相对简单, 但你有多种选择 网格在合并控件 外在大小调整提供内在大小的灵活性, 因此非常适合此类布局 这是因为网格是专为二维内容设计的布局方法。 也就是说,同时以行和列进行布局。

创建网格布局时,您可以定义一个包含行和列的网格。 然后,将各个项放置在该网格上, 或允许浏览器自动将其放入您创建的单元格中。 网格中有很多内容, 但还会简要了解 您很快就能创建网格布局。

概览

网格的用途是什么? 网格布局具有以下功能。 您将在本指南中了解所有类型。

  1. 可以使用行和列定义网格。 您可以选择如何调整这些行和列轨道的大小,也可以根据内容的大小进行调整。
  2. 网格容器的直接子级将自动放置在此网格上。
  3. 或者,您可以将内容放置在所需的确切位置。
  4. 您可为网格上的线条和区域命名,以方便放置。
  5. 网格容器中的空闲空间可以分布在轨道之间。
  6. 网格项可以在其区域内对齐。

网格术语

Grid 引入了许多新术语,因为这是 CSS 首次有真实的布局系统。

网格线

网格由线条组成 分别在水平和垂直方向上放置 如果网格有四列, 将有五列行,包括最后一列后面的一行。

行从 1 开始编号, 并遵循组件的书写模式和脚本方向进行编号。 也就是说,第 1 列将位于左侧,采用从左到右的语言,例如英语, 而右侧则显示从右向左书写的语言,如阿拉伯语。

网格线的示意图

网格轨道

轨迹是两条网格线之间的空间。 行轨迹位于两个行线之间,列轨迹位于两个列线之间。 在创建网格时,我们通过为它们指定尺寸来创建这些轨道。

网格轨迹的示意图

网格单元

网格单元是由行轨道和列轨道的交集定义的网格上的最小空间。 就像表格单元格或电子表格中的单元格一样。 如果您定义了网格 它们会自动在每个定义的网格单元格中列出一项。

网格单元的示意图

网格区域

多个网格单元格。 通过让某项内容跨越多个轨道,可创建网格区域。

网格区域的示意图

间隔

轨道之间的地沟或小巷。 为了调整大小,它们就像常规轨道一样。 您不能将内容放入间隔中,但可以跨越网格项。

有间隙的网格的示意图

网格容器

应用了 display: grid 的 HTML 元素。 从而为直接子项创建新的网格格式设置上下文。

.container {
  display: grid;
}

网格项

网格项是网格容器的直接子级。

<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

行和列

要创建基本网格,您可以定义一个包含三个列轨迹的网格, 两个行的轨道,并在轨道之间留出 10 像素的间距,如下所示。

.container {
    display: grid;
    grid-template-columns: 5em 100px 30%;
    grid-template-rows: 200px auto;
    gap: 10px;
}

此网格展示了术语部分描述的许多内容。 它有三个列轨迹。 每首曲目使用不同的长度单位。 它有两个行轨道 一个使用长度单位,另一个自动使用。 当汽车的用途是调整尺寸时,可以将其视为与内容一样大。 默认情况下,轨道会自动调整大小。

如果类为 .container 的元素包含子项, 它们就会立即在此网格上进行布局。您可以通过下面的演示了解实际操作。

Chrome 开发者工具中的网格叠加层可帮助您了解网格的各个部分。

在 Chrome 中打开该演示。 检查使用灰色背景的元素(ID 为 container)。 在 DOM 中选择 .container 元素旁边的网格标记以突出显示网格。 在“布局”标签页中 从下拉菜单中选择显示行号即可查看网格中的行号。

<ph type="x-smartling-placeholder">
</ph> 如图片说明和说明中所述 <ph type="x-smartling-placeholder">
</ph> Chrome 开发者工具中突出显示的网格,显示了行号、单元格和轨迹。

固有尺码关键字

除了 尺寸单位 网格轨道可以使用固有大小关键字。 这些关键字在 Box 大小规范中定义 并在 CSS 文件中添加其他调整框的大小的方法 不仅仅是网格轨迹

  • min-content
  • max-content
  • fit-content()

min-content 关键字可在不溢出曲目内容的情况下尽可能缩小曲目。 将示例网格布局更改为大小为 min-content 的三个列轨迹 意味着与曲目中最长的单词一样窄。

max-content 则会产生相反的效果。 曲目会变宽,以便所有内容显示在一个不间断的长字符串中。 这可能会导致溢出,因为字符串不会换行。

fit-content() 函数起初的作用类似于 max-content。 但是,一旦曲目达到您传入函数的大小, 内容开始换行。 因此,fit-content(10em) 将创建一个小于 10em 的音轨, 如果 max-content 的大小小于 10em, 但绝不会超过 10em。

在下一个演示中,通过更改网格轨道的尺寸,试用不同的固有尺寸关键字。

fr 单位

我们有现有的长度维度、百分比以及这些新的关键字。 还有一个仅适用于网格布局的特殊大小调整方法。 这是 fr 单元, 一个灵活长度,用于说明网格容器中可用空间的份额。

fr 单元的运作方式与在 Flexbox 中使用 flex: auto 的方式类似。 它会在内容经过布局后分配空间。 因此,要使三个列都获得相同份额的可用空间:

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
}

由于 fr 单元会共享可用空间, 它可以与固定尺寸的间隙轨道或固定尺寸的轨道结合使用。 要想让组件具有固定尺寸的元素,并让第二个轨道占据任何剩余空间, 您可以用作 grid-template-columns: 200px 1fr 的曲目列表。

为 fr 单位使用不同的值将按比例共享空间。 值越大,能占用的可用空间就越多。 在下面的演示中,更改第三音轨的值。

minmax() 函数

浏览器支持

  • Chrome:57。 <ph type="x-smartling-placeholder">
  • Edge:16。 <ph type="x-smartling-placeholder">
  • Firefox:52。 <ph type="x-smartling-placeholder">
  • Safari:10.1. <ph type="x-smartling-placeholder">

来源

此函数表示您可以为曲目设置大小下限和上限。 这项功能非常有用。 如果以上面分配剩余空间的 fr 单元为例, 可以使用 minmax()minmax(auto, 1fr)。 网格关注的是内容的固有大小, 然后在为内容留出足够的空间后分配可用空间 也就是说,你获得的曲目可能份额相同 网格容器中所有可用空间的总和。

要强制某个轨道平均占据网格容器中的空间份额减去间隙,请使用 minmax。 将 1fr 作为轨道大小替换为 minmax(0, 1fr)。 这会使曲目的最小尺寸为 0,而不是最小内容尺寸。 然后,网格将采用容器中所有可用的尺寸 减去填补缺口所需的尺寸 剩下的事情可以分享给你们

repeat() 表示法

浏览器支持

  • Chrome:57。 <ph type="x-smartling-placeholder">
  • Edge:16。 <ph type="x-smartling-placeholder">
  • Firefox:76。 <ph type="x-smartling-placeholder">
  • Safari:10.1. <ph type="x-smartling-placeholder">

来源

如果您想创建一个 12 列的轨道网格,并使其各列相等, 您可以使用以下 CSS

.container {
    display: grid;
    grid-template-columns:
      minmax(0,1fr),
      minmax(0,1fr),
      minmax(0,1fr),
      minmax(0,1fr),
      minmax(0,1fr),
      minmax(0,1fr),
      minmax(0,1fr),
      minmax(0,1fr),
      minmax(0,1fr),
      minmax(0,1fr),
      minmax(0,1fr),
      minmax(0,1fr);
}

或者,您可以使用 repeat():

.container {
    display: grid;
    grid-template-columns: repeat(12, minmax(0,1fr));
}

repeat() 函数可用于重复曲目详情的任何部分。 例如,您可以重复播放某首曲目的模式。 你还可以制作一些常规曲目和一个重复时段。

.container {
    display: grid;
    grid-template-columns: 200px repeat(2, 1fr 2fr) 200px; /*creates 6 tracks*/
}

auto-fillauto-fit

您可以结合运用所学的有关轨道大小、 minmax(),然后重复上述操作, 使用网格布局创建有用的图案。 例如,您可能不想指定曲目数 而是应尽可能多创建适合你容器的数量

为此,您可以使用 repeat() 以及 auto-fillauto-fit 关键字。 在下面的演示中,网格将创建适合容器的尽可能多的 200 像素轨道。 在新窗口中打开演示,看看网格随着视口大小的变化而变化。

在演示中,我们会尽可能多地获取曲目。 但是,这种轨道并不灵活。 这样,图片末尾会有间隙,直到有足够的空间再容纳 200 像素的曲目。 如果您添加 minmax() 函数, 您可以请求任意数量的曲目,大小下限为 200 像素,上限为 1fr。 然后,Grid 会布置 200 像素的轨道,并将剩余空间平均分配给它们。

这样就可以创建一个二维自适应布局,而无需进行任何媒体查询。

auto-fillauto-fit 之间存在细微差异。 在下一个演示中,我们将使用上面介绍的语法使用网格布局: 但在网格容器中只有两个网格项。 使用 auto-fill 关键字,可以看到已创建的空轨道。 将关键字更改为 auto-fit,并且轨道会收起为 0。 这意味着灵活轨道现在会增大以占用空间。

除此之外,auto-fillauto-fit 关键字的运作方式完全相同。 第一个音轨填满后,这两者之间就没有区别了。

自动放置

到目前为止,您在演示中已经看到过自动放置网格。 每个单元格一个单元格中的项会按照它们在来源中的显示顺序放置在网格上。 对于许多布局来说,您可能只需要这样做。 如果您需要更多控制权,则不妨执行几项操作。 第一种是调整自动展示位置的布局。

将内容放入列中

网格布局的默认行为是沿着行放置项。 您可以改为使用 grid-auto-flow: column 将项放入列中。 您需要定义行轨道,否则,这些项将创建固有的列轨道, 将所有内容放在一个长行中

这些值与文档的写入模式相关。 行始终按句子的方向在文档或组件的书写模式下运行。 在下一个演示中,您可以更改 grid-auto-flow 的值和 writing-mode 属性模式。

跨越轨道

您可以使自动放置布局中的部分或全部项目跨多个轨道。 使用 span 关键字加上要跨行的行数作为 grid-column-endgrid-row-end 的值。

.item {
    grid-column-end: span 2; /* will span two lines, therefore covering two tracks */
}

由于您尚未指定 grid-column-start, 系统会使用auto的初始值,并按照自动放置规则放置位置。 您还可以使用简写形式 grid-column 指定相同的内容:

.item {
    grid-column: auto / span 2;
}

填补缺口

自动放置的布局,其中某些项跨越多个轨道 可能会导致网格中有一些未填充的单元格。 采用完全自动放置的布局的网格布局的默认行为 始终向前推进 系统会按照它们在来源中的顺序来放置这些项, 或对 order 属性进行任何修改。 如果空间不足,无法容纳某件商品 网格就会留下一个间隙,并移动到下一曲目。

下一个演示展示了此行为。 该复选框将采用密集打包模式。 将 grid-auto-flow 的值设置为 dense 可以实现这一点。 设置好此值后 网格稍后会获取布局中的项,并使用它们来填充间隙。 这可能意味着,显示屏不再遵循逻辑顺序。

放置内容

您已经有了 CSS 网格中的很多功能。 现在,让我们来看看如何在所创建的网格上放置项。

首先要记住的是,CSS 网格布局基于带编号的网格。 在网格上放置元素的最简单方法是将它们从一行放置到另一行。 您将在本指南中找到放置项的其他方法, 但您也可以随时访问这些带编号的行

可用于按行号放置项目的属性包括:

它们具有简写形式,可让您同时设置开始行和结束行:

要放置您的内容,请设置应放置该内容的网格区域的起点和终点线。

.container {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    grid-template-rows: repeat(2, 200px 100px);
}

.item {
    grid-column-start: 1; /* start at column line 1 */
    grid-column-end: 4; /* end at column line 4 */
    grid-row-start: 2; /*start at row line 2 */
    grid-row-end: 4; /* end at row line 4 */
}

Chrome 开发者工具可以直观地查看各行,以便检查您的项的放置位置。

行编号遵循组件的书写模式和方向。 在下一个演示中,更改书写模式或方向 看看项目的位置是如何与文本流动方式保持一致的。

堆叠商品

使用基于线条的定位时,您可以将项放置在网格的同一个单元格中。 也就是说,您可以将内容堆叠在一起 或导致一项内容部分重叠。 来源中较晚的项会显示在较早的项上方。 您可以使用 z-index 更改此堆叠顺序,就像更改已放置位置项一样。

负数行号

使用 grid-template-rowsgrid-template-columns 创建网格时 您可以创建所谓的“显式网格”。 这是一个您已定义并为路线指定大小的网格。

有时,某些项会显示在此显式网格之外。 例如: 您可以定义列轨道,然后添加几行网格项,而无需定义行轨道。 默认情况下,轨道会自动调整大小。 您也可以使用 grid-column-end 将某个项放置在定义的显式网格之外。 在这两种情况下,网格都会创建轨迹以使布局正常运行。 并且这些轨迹称为隐式网格。

在大多数情况下,如果您使用的是隐式网格或显式网格,情况并不会造成任何影响。 但是,使用基于行的展示位置时,您可能会发现这两者之间的主要区别。

使用负数行号,您可以将项从显式网格的末行放置。 如果您希望某项内容从第一列到最后一列行,这会非常有用。 在这种情况下,您可以使用 grid-column: 1 / -1。 项将向右延伸至显式网格。

不过,这仅适用于显式网格。 对 3 行自动放置的项目进行布局 在这里,您希望第一项跨越到网格末端。

包含 8 个同级网格项的边栏

您可能会认为,您可以将该商品指定为 grid-row: 1 / -1。 在下面的演示中,您可以看到这不起作用。 轨道是在隐式网格中创建的, 无法使用 -1 到达网格的末端。

调整隐式轨道的大小

默认情况下,在隐式网格中创建的轨道会自动调整大小。 不过,如果您想控制行的大小 使用 grid-auto-rows 属性, 而对于列 grid-auto-columns

如需创建大小至少为 10em 且最大大小为 auto 的所有隐式行,请执行以下操作:

.container {
    display: grid;
    grid-auto-rows: minmax(10em, auto);
}

创建采用 100 像素和 200 像素宽度轨道的隐式列。 在本例中,第一个隐含列为 100 像素 第二个 200 像素 第三个 100px,依此类推

.container {
    display: grid;
    grid-auto-columns: 100px 200px;
}

已命名的网格线

如果这些行包含名称而非数字,则可以更轻松地将列表项放入布局中。 你可以在方括号之间添加你选择的名称,为网格上的任意线条命名。 可以添加多个名称 并用方括号内的空格分隔。 有了命名的行后,就可以将它们代替数字了。

.container {
    display: grid;
    grid-template-columns:
      [main-start aside-start] 1fr
      [aside-end content-start] 2fr
      [content-end main-end]; /* a two column layout */
}

.sidebar {
    grid-column: aside-start / aside-end;
    /* placed between line 1 and 2*/
}

footer {
    grid-column: main-start / main-end;
    /* right across the layout from line 1 to line 3*/
}

网格模板区域

您还可以为网格的区域命名,并将项目放置在这些命名区域中。 这一技巧非常实用,因为它可以让您直接看到组件在 CSS 中的样子。

首先,使用 grid-area 属性:

header {
    grid-area: header;
}

.sidebar {
    grid-area: sidebar;
}

.content {
    grid-area: content;
}

footer {
    grid-area: footer;
}

您可以采用除关键字 autospan 之外的任何其他名称。 在为所有项命名后 使用 grid-template-areas 属性来定义每一项将跨越的网格单元格。 每一行都在引号内定义。

.container {
    display: grid;
    grid-template-columns: repeat(4,1fr);
    grid-template-areas:
        "header header header header"
        "sidebar content content content"
        "sidebar footer footer footer";
}

使用 grid-template-areas 时需遵循一些规则。

  • 该值必须是不含空单元格的完整网格。
  • 如需跨越轨道,请重复名称。
  • 通过重复名称创建的区域必须为矩形,且不能断开连接。

如果您违反上述任何规则,则该值将被视为无效并被丢弃。

如需在网格中留出空白区域,请使用 . 或倍数,且它们之间没有空格。 例如,如需将网格上的第一个单元格留空,我可以添加一系列 . 字符:

.container {
    display: grid;
    grid-template-columns: repeat(4,1fr);
    grid-template-areas:
        "....... header header header"
        "sidebar content content content"
        "sidebar footer footer footer";
}

由于整个布局是在一个位置定义的 它让您可以直接使用媒体查询重新定义布局。 在下一个示例中,我创建了一个两列的布局,该布局会移至三列 方法是重新定义 grid-template-columnsgrid-template-areas 的值。 在新窗口中打开示例,以调整视口大小并查看布局更改。

您还可以查看 grid-template-areas 属性与 writing-mode 和方向之间的关系, 就像使用其他网格方法一样。

简写属性

有两个简写属性可让您一次性设置多个网格属性。 在真正分解之前,这些 API 看起来有点令人困惑。 至于您想使用还是喜欢使用长手,则由您自己决定。

grid-template

浏览器支持

  • Chrome:57。 <ph type="x-smartling-placeholder">
  • Edge:16。 <ph type="x-smartling-placeholder">
  • Firefox:52。 <ph type="x-smartling-placeholder">
  • Safari:10.1. <ph type="x-smartling-placeholder">

来源

grid-template 属性是 grid-template-rowsgrid-template-columnsgrid-template-areas 的简写形式。 首先定义行 以及 grid-template-areas 的值。 在 / 之后添加列大小调整。

.container {
    display: grid;
    grid-template:
      "head head head" minmax(150px, auto)
      "sidebar content content" auto
      "sidebar footer footer" auto / 1fr 1fr 1fr;
}

grid 个房源

浏览器支持

  • Chrome:57。 <ph type="x-smartling-placeholder">
  • Edge:16。 <ph type="x-smartling-placeholder">
  • Firefox:52。 <ph type="x-smartling-placeholder">
  • Safari:10.1. <ph type="x-smartling-placeholder">

来源

grid 简写形式的使用方式与 grid-template 简写形式完全相同。 以这种方式使用时,它会将接受的其他网格属性重置为初始值。 全部内容包括:

  • grid-template-rows
  • grid-template-columns
  • grid-template-areas
  • grid-auto-rows
  • grid-auto-columns
  • grid-auto-flow

您也可以使用此简写形式定义隐式网格的行为, 例如:

.container {
    display: grid;
    grid: repeat(2, 80px) / auto-flow  120px;
}

对齐

网格布局使用的对齐属性与 flexbox。 在网格中,内联轴上始终使用以 justify- 开头的属性, 句子在书写模式下的运行方向。

块轴会使用以 align- 开头的属性, 文本块在书写模式下的布局方向。

分配额外空间

在这个演示中,网格大于布置固定宽度轨道所需的空间。 这意味着网格的内嵌维度和块维度都有空间。 尝试使用不同的 align-contentjustify-content 值,看看轨道的行为方式。

请注意,在使用 space-between 等值时,间隔会如何变大, 跨越两个轨道的任何网格项也会变大,以吸收增加到间隔中的额外空间。

移动内容

具有背景颜色的项看起来完全填满了它们所在的网格区域, 因为 justify-selfalign-self 的初始值为 stretch

在演示中,更改 justify-itemsalign-items 的值,看看这会如何更改布局。 网格区域的大小保持不变, 而是在指定的区域内移动这些项。

检查您的理解情况

测试您对网格的掌握情况

以下哪些是 CSS 网格术语?

线形
网格会被水平和垂直方向的分隔符分隔。
圈子
抱歉,CSS 网格中没有圆圈的概念。
细胞
行与列的单一交集可创建一个网格单元格。
区域
将多个单元格放到一起。
火车
抱歉,CSS 网格中没有列车的概念。
空缺
单元格之间的空格。
曲目
单行或一列是网格中的一条轨迹。
main {
  display: grid;
}

网格的默认布局方向是什么?

如果未指定任何列,网格子项将照常按块方向布局。
如果存在 grid-auto-flow: column,则网格将布局为列。

auto-fitauto-fill 有什么区别?

auto-fit 会拉伸单元格以适应容器,而 auto-fill 不能。
auto-fill 会将尽可能多的项放入模板中,而不进行拉伸。Google 健身会调整
auto-fit 会拉伸容器以适应子元素,而 auto-fill 可让子元素适应容器。
这并非这些属性的行为方式。

什么是 min-content

与 0% 相同
0% 是父框的相对值,而 min-content 是父框中的字词和图片相对值。
最小的字母
虽然存在最小的字母,但这些字母不是 min-content 所指的意思。
最长的字词或图片。
在短语“CSS is awesome”中,“超棒”一词将是 min-content

什么是 max-content

最长的句子或最大的图片。
这是框内容要求或已指定的大小上限。它是最宽的句子或最宽的图片。
最长的字母。
虽然存在最长的字母,但字母不是 max-content 所指的字母。
最长的字词。
最长的一个字词为 min-content

什么是自动放置?

网格何时获取子项,并根据浏览器启发法将它们放在最佳顺序中。
任何浏览器都不会更改内容顺序,只有您自己的样式会更改。
网格子项被赋予 grid-area 并被放置在该单元格中时。
这是指显式放置,而不是自动放置。
当未分配的网格项被放置到布局模板中后。
没有明确区域的网格项将放置在下一个可用的网格单元格中

资源

本指南概述了网格布局规范的不同部分。 如需了解详情,请参阅以下资源。