介绍
CSS 网格布局用于将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系。
与 table 表格一样,网格布局让我们能够按行或列来对齐元素,但在布局上,网格比表格更容易做到且更简单。
与弹性盒
网格布局和 flex 弹性盒布局的主要区别在于弹性盒布局是一维布局(沿横向或纵向的),而网格布局是二维布局(同时沿着横向和纵向)。
弹性盒的不足
比如以下一个宽度 500px 的容器内有五个元素区域,我们使用弹性盒来对齐这些区域。在每个子项目上设置 flex: 1 1 150px;,以在 150px 基准上伸缩。flex-wrap 属性为 wrap,从而当容器变得太窄时,元素会换到新的一行。
| 1 | <div class="wrapper"> | 
| 1 | .wrapper { | 
你可以看到有两个元素被换到了新行。这两个元素共享了这行的可用空间,并没有与上一行的元素对齐。这表示当你允许弹性元素换行时,每个新行都变成了一个新的弹性容器。那有没有可以在新行也与上一行保持对齐的方法?答案是网格。
我们用网格更简单地创建同样的布局。只需要给这些子元素设置设置 3 个 1fr 的列,并不需要任何其他属性,它们会自动按顺序填充到网格的单元格中。你可以看到它们按网格规整的排列,行与行、列与列对齐。当有 5 个子元素时,第二行的尾部会留出一个空隙。
| 1 | .wrapper { | 
fr 关键字为 fraction 的缩写,表示了网格容器中的一段可变长度。repeat() 函数用于在 CSS 中快速编写网格,repeat(3, 1fr) 相当于 1fr 1fr 1fr。
如何选择该用网格还是弹性盒?
- 我只需要按行或者列控制布局?那就用弹性盒子。
- 我需要同时按行和列控制布局?那就用网格。
弹性盒关注的是内容,而网格侧重布局。当你使用弹性盒,并发现自己禁用了一些弹性特性,那你可能需要的是 CSS 网格布局。例如,你给一个弹性元素设置百分比宽度来使它和上一行的元素对齐。这种情况下,网格很可能是一个更好的选择。
详细可以 MDN 了解以下,接下来我们来使用 grid 实现各种布局。
超级居中布局
| 1 | .parent { | 
其中 place-items 属性是一个简写形式。
| 1 | place-items: <align-items> <justify-items>; | 
align-items 属性控制垂直位置,justify-items 属性控制水平位置。如果未提供第二个值,则第一个值作为第二个值的默认值。所以,place-items: center; 等同于 place-items: center center;。
侧边栏布局
一个边栏,一个主栏。
| 1 | .container { | 
这里使用 minmax(最小值, 最大值) 函数定义了一个长宽范围的闭区间,表示列宽不会收缩小于 150px 且不会拉伸大于容器宽度的 25%。每个参数分别是 <length>、<percentage>、<flex> 的一种,或者是 max-content、min-content、或 auto 之一。如果 最大值 < 最小值,则 最大值 被忽略并返回 最小值。<flex> 值作为 最大值 时设置网格轨道的弹性系数;作为 最小值 时无效。auto
作为最大值时,等价于 max-content;作为 最小值 时,它表示轨道中单元格最小长宽(min-width/min-height)的最大值。
三明治布局
页面在垂直方向上,分成三部分:页眉、内容区、页脚。这个布局会根据设备宽度,自动适应,并且不管内容区有多少内容,页脚始终在容器底部(粘性页脚)。
| 1 | .container { | 
经典圣杯布局
最常用的布局,所以被比喻为圣杯。它将页面分成五个部分,除了页眉和页脚,内容区分成左边栏、主栏、右边栏。
| 1 | .container { | 
grid-template 是 grid-template-rows、grid-template-columns 与 grid-template-areas 的简写形式。有三种写法:
- 关键字,默认 grid-template: none;。
- grid-template-rows / grid-template-columns,例如本例子中的- grid-template: auto 1fr auto / auto 1fr auto;。
- grid-template-areas grid-template-rows / grid-template-column,例如:- 1 
 2
 3
 4- grid-template: 
 "a a a" 40px
 "b c c" 40px
 "b c c" 40px / 1fr 1fr 1fr;
圣杯布局2
将页面分成四个部分,除了页眉和页脚,内容区分成左边栏、主栏。
| 1 | #container { | 
这里自定义了四个 grid-area 标识,并在  grid-template 中引用它们。然后页眉被分配了 30px 固定高度和 100% 的宽度;左边栏被分配了 1fr + 30px 弹性高度和 120px 固定宽度;主栏被分配了 1fr 的弹性高度和 1fr 的弹性宽度;页脚被分配了 30px 的固定高度和 1fr 的弹性宽度。
瀑布流布局
表现为参差不齐的多栏布局,以图片为主,大小不一的图片按照一定的规律排列。随着页面滚动条向下滚动,还会不断加载数据块并附加至当前尾部。
| 1 | .container { | 
grid-auto-columns 属性和 grid-auto-rows 属性表示浏览器将根据指定值自动设置网格的列宽和行高。它们的写法与 grid-template-columns 和 grid-template-rows 完全相同。如果没有指定这四个属性,浏览器会根据单元格内容的大小,决定网格的列宽和行高。
跨网格布局
另一个经典布局:12 网格布局。
| 1 | .parent { | 
repeat(12, 1fr); 表示 12 弹性宽度列。grid-column: 1 / 13 将跨越从第一列到最后一列(第 13 列),总共占 12 列。也可以使用 span 关键字,设置起始线,然后设置从该起点跨越的列数。grid-column: 1 / span 12 等效于 grid-column: 1 / 13 ,而 grid-column: 2 / span 6 等效于 grid-column: 2 / 8 。