开发者-导航 猿导航

grid 网格布局

发布时间:

目录

原文地址 来源 Google web dev

简单行和列布局 #

css #

body{
	background-color: #dadce0;
}
.container {
	display: grid;
	grid-template-columns: 5em 100px 30%;
	grid-template-rows: 200px auto;
	gap: 10px;
	height: 300px;
}
.container div{
	 background-color: #f3f4f4;
}

html #

<div class="code-container">
	<div>item1</div>
	<div>item2</div>
	<div>item3</div>
	<div>item4</div>
	<div>item5</div>
	<div>item6</div>
</div>

效果 #

谷歌浏览器 F12 开发者工具中查看布局详情,Chrome 开发者工具中的网格叠加层 可帮助您了解网格的各个部分。

item1
item2
item3
item4
item5

布局详情

Chrome DevTools 中突出显示的网格会显示行号、单元格和轨迹。

内在尺寸关键词 #

min-content 关键字将使轨道尽可能小,而轨道内容不会溢出。将示例网格布局更改为具有 min-content 大小的三列轨道将意味着它们变得与轨道中最长的单词一样窄。

max-content 关键字具有相反的效果。轨道将变得足够宽,以便所有内容都可以显示在一个长而不间断的字符串中。这可能会导致溢出,因为字符串不会换行。

fit-content() 函数最初的作用类似于 max-content。但是,一旦轨道达到您传递给函数的大小,内容就会开始换行。因此,如果最大内容大小小于 10em,则 fit-content(10em) 将创建小于 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() 函数 #

此功能意味着您可以设置轨道的最小和最大尺寸。这可能非常有用。如果我们以上面的 fr 单元为例,它分配剩余空间,则可以使用 minmax() 将其写为 minmax(auto, 1fr)。网格查看内容的固有大小,然后在为内容提供足够的空间后分配可用空间。这意味着您可能无法获得每个轨道均等地共享网格容器中所有可用空间的轨道。

要强制轨道占用网格容器中减去间隙的相同空间,请使用 minmax。将 1fr 替换为 minmax(0, 1fr) 作为轨道大小。这使得轨道的最小大小为 0,而不是最小内容大小。然后,Grid 将获取容器中的所有可用尺寸,扣除任何间隙所需的尺寸,并根据您的 fr 单位共享其余部分

repeat()符号 #

如果您想创建一个具有相等列的 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-fill 和 auto-fit #

自动填充和自动调整

您可以结合您所学到的有关轨道大小、minmax()repeat 的所有内容,以创建具有网格布局的有用模式。也许您不想指定列轨道的数量,而是希望创建适合容器的尽可能多的列轨道。

您可以使用 repeat()auto-fillauto-fit 关键字来实现此目的。在下面的演示中,网格将创建尽可能多的 200 像素轨道,以适合容器。在新窗口中打开演示,看看当您更改视口大小时网格如何变化。

在演示中,我们获得了尽可能多的曲目。然而,轨道并不灵活。您将在末端出现间隙,直到有足够的空间容纳另一个 200 像素轨道。如果添加 minmax() 函数,您可以请求尽可能多的轨道,最小尺寸为 200 像素,最大尺寸为 1fr。然后网格布置 200 像素轨道,剩余空间均等分配给它们。

这将创建一个二维响应式布局,无需任何媒体查询。

auto-fillauto-fit 之间存在细微差别。在下一个演示中,使用上面解释的语法来玩网格布局,但网格容器中只有两个网格项。使用 auto-fill 关键字,您可以看到已创建空轨道。将关键字更改为 auto-fit,轨道会折叠至 0 大小。这意味着柔性轨道现在会增长以占用空间。

否则,aufo-fillauto-fit 关键字的作用完全相同。一旦第一条轨道被填满,它们之间就没有区别了。

元素排列方式 #

到目前为止,您已经在演示中看到了网格元素排列的工作原理。元素按照它们在布局中出现的顺序放置在网格上的每个单元格中。对于许多布局来说,这可能就是您所需要的。如果您需要更多控制,那么您可能需要做一些事情。第一个是调整 grid-auto-flow 布局。

将元素放置在列中(默认行布局) #

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

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

跨越轨道(跨行跨列) #

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

.item {
    grid-column-end: span 2; /* 将跨越两条线,因此覆盖两条轨道 */
}

由于您尚未指定 grid-column-start,因此它使用 auto 的初始值并根据自动放置规则进行放置。您还可以使用简写 grid-column 来指定相同的内容:

.item {
    grid-column: auto / span 2;
}
code css
.code-container {
	display: grid;
	grid-template-columns: 5em 100px 30%;
	grid-template-rows: 200px auto;
	gap: 10px;
	height: 300px
}

.code-container>div {
	background-color: #c7ab1a
}

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

.code-row-span {
	grid-row: auto / span 2;
}
code html
<div class="code-container">
	<div></div>
	<div class="code-column-span">跨列</div>
	<div class="code-row-span">跨行</div>
	<div>非常长长</div>
	<div>非常长长长</div>
	<div>非常长长长长</div>
</div>
效果图 html
跨列
跨行
非常长长
非常长长长
非常长长长长

跨行跨列

Chrome DevTools 中突出显示的网格会显示行号、单元格和轨迹。

填补空白 #

自动放置的布局(其中某些元素跨越多个轨道)可能会导致网格中包含一些未填充的单元格。具有完全自动放置布局的网格布局的默认行为是始终向前推进。这些元素将根据它们在源中的顺序或对 order 属性进行的任何修改进行放置。如果没有足够的空间来容纳元素,网格将留下间隙并移动到下一个轨道。

下一个演示展示了这种行为。该复选框将应用密集包装模式。这是通过为 grid-auto-flow 指定 dense 来实现的。有了这个值,网格将在布局中稍后获取项目并使用它们来填充间隙。这可能意味着显示与逻辑顺序断开。

放置元素 #

您已经拥有 CSS Grid 的许多功能。现在让我们看看如何在我们创建的网格上放置元素。

首先要记住的是 CSS 网格布局基于编号行网格。将事物放置到网格上的最简单方法是将它们从一条线放置到另一条线。您将在本指南中发现放置物品的其他方法,但您始终可以访问这些编号的行。

可用于按行号放置元素的属性有:

它们具有允许您同时设置开始行和结束行的简写:

要放置元素,请设置应放置元素的网格区域的起始线和结束线。

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

.item {
    grid-column-start: 1; /* 从第 1 列开始 */
    grid-column-end: 4; /* 结束于第 4 列 */
    grid-row-start: 2; /* 从第 2 行开始 */
    grid-row-end: 4; /* 结束于第 4 行 */
}

Chrome DevTools 可以为您提供线条的视觉指南,以便检查您的元素的放置位置。

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

堆叠元素 #

使用基于行的定位,您可以将元素放置到网格的同一单元格中。这意味着您可以堆叠元素,或使一项与另一项部分重叠。源中较晚出现的元素将显示在较早出现的元素之上。您可以使用 z-index 更改此堆叠顺序,就像定位元素一样

负行号 #

当您使用 grid-template-rowsgrid-template-colums 创建网格时,您将创建所谓的显式网格。这是您已定义并指定轨道大小的网格。

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

大多数时候,无论您使用隐式网格还是显式网格,都没有什么区别。然而,通过基于行的布局,您可能会遇到两者之间的主要区别。

使用负行号,您可以从显式网格的末尾行放置元素。如果您希望元素从第一个列行跨越到最后一个列行,这会很有用。在这种情况下,您可以使用 grid-column: 1 / -1。该元素将直接延伸穿过显式网格。

然而,这仅适用于显式网格。采用三行自动放置项目的布局,您希望第一个项目跨越网格的结束线。

带有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 像素宽轨道图案的隐式列。在这种情况下,第一个隐式列将为 100px,第二个为 200px,第三个为 100px,依此类推。

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

grid-template-areas 命名网格线 #

如果行具有名称而不是数字,则可以更轻松地将元素放入布局中。您可以通过在方括号之间添加您选择的名称来命名网格上的任何行。可以添加多个名称,并在同一括号内用空格分隔。一旦命名了线,就可以使用它们来代替数字。

.container {
    display: grid;
    grid-template-columns:
      [main-start aside-start] 1fr
      [aside-end content-start] 2fr
      [content-end main-end]; /* 两列布局 */
}

.sidebar {
    grid-column: aside-start / aside-end;
    /* 放置在第 1 行和第 2 行之间*/
}

footer {
    grid-column: main-start / main-end;
    /* 位于第 1 行到第 3 行布局的右侧 */
}
code HTML
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>网格布局</title>
		<style>
			#page {
			  display: grid; /* 1.设置 display 为 grid */
			  width: 100%;
			  height: 250px;
			  grid-template-areas:
			    "head head"
			    "nav  main"
			    "nav  foot"; /* 2.区域划分 当前为 三行 两列 */
			  grid-template-rows: 50px 1fr 30px; /* 3.各区域 宽高设置 */
			  grid-template-columns: 150px 1fr;
			}
			
			#page > header {
			  grid-area: head; /* 4. 指定当前元素所在的区域位置,从 grid-template-areas 选取值 */
			  background-color: #8ca0ff;
			}
			
			#page > nav {
			  grid-area: nav;
			  background-color: #ffa08c;
			}
			
			#page > main {
			  grid-area: main;
			  background-color: #ffff64;
			}
			
			#page > footer {
			  grid-area: foot;
			  background-color: #8cffa0;
			}

		</style>
	</head>
	<body>
		<section id="page">
		  <header>Header</header>
		  <nav>Navigation</nav>
		  <main>Main area</main>
		  <footer>Footer</footer>
		</section>
	</body>
</html>

效果

Header
Main area
Footer

grid 属性 #

网格简写的使用方式与网格模板简写的使用方式完全相同。当以这种方式使用时,它将重置其接受的其他网格属性为其初始值。全套有:

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

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

资源 #

本指南概述了网格布局规范的不同部分。要了解更多信息,请查看以下资源。