CSS 网格布局指南

Avatar of Chris House
Chris House

我们关于 CSS 网格的综合指南,重点介绍了网格父容器和网格子元素的所有设置。

由 DigitalOcean 提供

DigitalOcean 提供您在任何阶段支持增长的云计算服务。 立即开始使用 200 美元免费积分!

获取海报!

经常参考本指南?这里有一个您可以打印的高分辨率图像!

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>

网格线

构成网格结构的分割线。它们可以是垂直的(“列网格线”)或水平的(“行网格线”),并且位于行或列的任一侧。这里黄色线是列网格线的示例。

网格轨道

两个相邻网格线之间的空间。你可以把它想象成网格的列或行。这是第二行和第三行网格线之间的网格轨道。

网格区域

由四条网格线包围的总空间。一个网格区域可以包含任意数量的网格单元。这里是第一行和第三行网格线之间,以及第一列和第三列网格线之间的网格区域。

网格项目

网格容器的子元素(即直接后代)。这里item元素是网格项目,但sub-item不是。

<div class="container">
  <div class="item"> </div>
  <div class="item">
    <p class="sub-item"> </p>
  </div>
  <div class="item"> </div>
</div>

网格单元

两个相邻行和两个相邻列网格线之间的空间。它是网格的单个“单元”。这里是第一行和第二行网格线之间,以及第二列和第三列网格线之间的网格单元。

CSS 网格属性

父元素的属性
(网格容器)

跳转链接

display

将元素定义为网格容器,并为其内容建立新的网格格式化上下文。

  • grid – 生成块级网格
  • inline-grid – 生成行内级网格
.container {
  display: grid | inline-grid;
}

将网格参数向下传递给嵌套元素(又称子网格)的能力已移至 CSS 网格规范的第 2 级。 这里有一个 快速说明.

grid-template-columns
grid-template-rows

使用用空格分隔的值列表定义网格的列和行。这些值表示轨道大小,它们之间的空格表示网格线。

  • <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];
}
Grid with user named lines

注意,一条线可以有多个名称。例如,这里第二条线将有两个名称: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

Example of grid-template-areas

声明中的每一行都需要具有相同的单元格数量。

您可以使用任意数量的相邻点号来声明单个空单元格。只要点号之间没有空格,它们就表示一个单元格。

请注意,此语法没有命名行,而是命名区域。当您使用此语法时,区域两端的行实际上会自动命名。如果您的网格区域的名称是 foo,则区域的起始行线和起始列线的名称将是 foo-start,其结束行线和结束列线的名称将是 foo-end。这意味着某些行可能具有多个名称,例如上面示例中最左边的行,它将具有三个名称:header-start、main-start 和 footer-start。

grid-template

用于设置 grid-template-rowsgrid-template-columns 和 grid-template-areas 的简写。

.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-columnsgrid-auto-rows 和 grid-auto-flow),这可能是在大多数情况下您想要执行的操作,建议使用 grid 属性而不是 grid-template

column-gap
row-gap
grid-column-gap
grid-row-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;
}
Example of grid-column-gap and grid-row-gap

间距仅在列/行 之间 创建,而不是在外部边缘。

注意: grid- 前缀将被删除, grid-column-gap 和 grid-row-gap 将被重命名为 column-gap 和 row-gap。Chrome 68+、Safari 11.2 Release 50+ 和 Opera 54+ 已支持无前缀属性。

gap
grid-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;
}
Example of justify-items set to start
.container {
  justify-items: end;
}
Example of justify-items set to end
.container {
  justify-items: center;
}
Example of justify-items set to center
.container {
  justify-items: stretch;
}
Example of justify-items set to stretch

此行为也可以通过 justify-self 属性在单个网格项目上设置。

align-items

沿 块(列) 轴对齐网格项目(与 justify-items 沿 内联(行) 轴对齐相反)。此值适用于容器内的所有网格项目。

  • stretch – 填充整个单元格高度(这是默认值)。
  • start – 将项目与单元格的起始边缘对齐。
  • end – 将项目与单元格的结束边缘对齐。
  • center – 将项目在其单元格的中心对齐。
  • baseline – 将项目对齐到文本基线baseline 有两个修饰符:first baselinelast baseline,在多行文本情况下,它们将使用第一行或最后一行文本的基线进行对齐。
.container {
  align-items: start | end | center | stretch;
}

示例

.container {
  align-items: start;
}
Example of align-items set to start
.container {
  align-items: end;
}
Example of align-items set to end
.container {
  align-items: center;
}
Example of align-items set to center
.container {
  align-items: stretch;
}
Example of align-items set to stretch

这种行为也可以通过 align-self 属性在单个网格项目上设置。

还有两个修饰符关键字 safeunsafe(用法类似于 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;
}
Example of justify-content set to start
.container {
  justify-content: end;    
}
Example of justify-content set to end
.container {
  justify-content: center;    
}
Example of justify-content set to center
.container {
  justify-content: stretch;    
}
Example of justify-content set to stretch
.container {
  justify-content: space-around;    
}
Example of justify-content set to space-around
.container {
  justify-content: space-between;    
}
Example of justify-content set to space-between
.container {
  justify-content: space-evenly;    
}
Example of justify-content set to 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;    
}
Example of align-content set to start
.container {
  align-content: end;    
}
Example of align-content set to end
.container {
  align-content: center;    
}
Example of align-content set to center
.container {
  align-content: stretch;    
}
Example of align-content set to stretch
.container {
  align-content: space-around;    
}
Example of align-content set to space-around
.container {
  align-content: space-between;    
}
Example of align-content set to space-between
.container {
  align-content: space-evenly;    
}
Example of align-content set to 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-columns
grid-auto-rows

指定任何自动生成的网格轨道(也称为 隐式网格轨道)的大小。当网格项目多于网格中的单元格,或者网格项目放置在显式网格之外时,会创建隐式轨道。(请参阅 显式网格和隐式网格之间的区别

  • <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;
}
Example of 2x2 grid

这将创建一个 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;
}
Example of implicit tracks

我们告诉 .item-b 从第 5 列线开始,到第 6 列线结束, 但我们从未定义过第 5 列线或第 6 列线。因为我们引用了不存在的行,所以会创建宽度为 0 的隐式轨道来填补间隙。可以使用 grid-auto-columns 和 grid-auto-rows 指定这些隐式轨道的宽度。

.container {
  grid-auto-columns: 60px;
}
grid-auto-columns-rows

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-bitem-citem-d)如何在可用行中流动

Example of grid-auto-flow set to row

如果我们将 grid-auto-flow 设置为 column,则 item-bitem-citem-d 会沿着列向下流动

.container {
  display: grid;
  grid-template-columns: 60px 60px 60px 60px 60px;
  grid-template-rows: 30px 30px;
  grid-auto-flow: column;
}
Example of grid-auto-flow set to column

grid

在单个声明中设置以下所有属性的简写形式:grid-template-rowsgrid-template-columnsgrid-template-areasgrid-auto-rowsgrid-auto-columnsgrid-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-areasgrid-template-rowsgrid-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;    
}

Properties for the Children
(Grid Items)

跳转链接

floatdisplay: inline-blockdisplay: table-cellvertical-aligncolumn-* 属性对网格项目没有影响。

grid-column-start
grid-column-end
grid-row-start
grid-row-end

通过引用特定网格线来确定网格项目在网格中的位置。 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;
}
Example of grid-row/column-start/end
.item-b {
  grid-column-start: 1;
  grid-column-end: span col4-start;
  grid-row-start: 2;
  grid-row-end: span 2;
}
Example of grid-row/column-start/end

如果没有声明 grid-column-end/grid-row-end ,则项目将默认跨越 1 个轨道。

项目可以相互重叠。您可以使用 z-index 来控制它们的堆叠顺序。

DigitalOcean 的这篇文章 中了解更多关于 span 符号的信息。

grid-column
grid-row

分别是 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;
}
Example of grid-column/grid-row

如果没有声明结束行值,则项目将默认跨越 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;
}
Example of grid-area

justify-self

在 内联(行) 轴线上对齐网格项目(与 align-self 沿 块级(列) 轴线对齐相反)。此值应用于单个单元格内的网格项目。

  • start – 将网格项目对齐到单元格的起始边
  • end – 将网格项目对齐到单元格的结束边
  • center – 将网格项目对齐到单元格的中心
  • stretch – 填充整个单元格宽度(这是默认值)。
.item {
  justify-self: start | end | center | stretch;
}

示例

.item-a {
  justify-self: start;
}
Example of justify-self set to start
.item-a {
  justify-self: end;
}
alt="Example
.item-a {
  justify-self: center;
}
Example of justify-self set to center
.item-a {
  justify-self: stretch;
}
Example of justify-self set to stretch

要设置 所有 网格项目对齐方式,此行为也可以通过 justify-items 属性在网格容器上设置。

align-self

在 块级(列) 轴线上对齐网格项目(与 justify-self 沿 内联(行) 轴线对齐相反)。此值应用于单个网格项目内的内容。

  • start – 将网格项目对齐到单元格的起始边
  • end – 将网格项目对齐到单元格的结束边
  • center – 将网格项目对齐到单元格的中心
  • stretch – 填充整个单元格高度(这是默认值)。
.item {
  align-self: start | end | center | stretch;
}

示例

.item-a {
  align-self: start;
}
Example of align-self set to start
.item-a {
  align-self: end;
}
Example of align-self set to end
.item-a {
  align-self: center;
}
Example of align-self set to center
.item-a {
  align-self: stretch;
}
Example of align-self set to 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;
}
place self set to center
.item-a {
  place-self: center stretch;
}
place set set to 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,其中包含更多详细信息。数字表示浏览器从该版本及更高版本开始支持该功能。

桌面

ChromeFirefoxIEEdgeSafari
575211*1610.1

移动/平板

Android ChromeAndroid FirefoxAndroidiOS Safari
12712712710.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-gapgrid-row-gapgrid-column-gap 使用长度、百分比或 calc。
  • grid-template-columnsgrid-template-rows 可以使用长度、百分比或 calc 的简单列表来表示,只要列表中的长度、百分比或 calc 组件的值不同即可。

截至目前,在所有测试过的浏览器中,仅实现了对 (grid-)gap(grid-)row-gap(grid-)column-gap 的动画支持。

浏览器(grid-)gap(grid-)row-gap(grid-)column-gapgrid-template-columnsgrid-template-rows
Firefox支持 ✅ 53+支持 ✅ 66+支持 ✅ 66+
Safari 12.0不支持 ❌不支持 ❌不支持 ❌
Chrome支持 ✅ 66+不支持 ❌不支持 ❌
Chrome for Android 66+、Opera Mini 33+支持 ✅不支持 ❌不支持 ❌
Edge支持 ✅ 16+不支持 ❌不支持 ❌

CSS 网格技巧!

学习 CSS Grid

CSS 网格视频

更多 CSS 网格资源