Grid 布局又称网格布局,是W3C提出的一个二维布局系统,它与 Flex 布局有一定的相似性,都可以指定容器内部多个项目的位置。但它们也存在重大区别。Flex 布局是轴线布局,只能指定”项目”针对轴线的位置,可以看作是一维布局。Grid 布局则是将容器划分成”行”和”列”,产生单元格,然后指定”项目所在”的单元格,可以看作是二维布局。目前为止Grid布局是CSS中最为强大的布局方案。

一、基础概念与浏览器支持

截止目前为止许多浏览器都提供了对 CSS Grid 的原生支持,而且无需加浏览器前缀:Chrome(包括 Android ),Firefox,Edge,Safari(包括iOS)和 Opera 。 另一方面,Internet Explorer 10和11也支持Grid布局,但是是以一个过时的语法实现。

各大主流浏览器对于Grid布局的支持情况如下图所示:

PC端浏览器:

学习CSS Grid布局前,我们先需要了解以下基础概念:

1、网格容器(Grid Container)

采用Grid 网格布局的元素称为网格容器,即应用display: grid的元素。

2、网格项目(Grid Item)

网格容器内部采用Grid 网格布局的直接子元素即为网格项目,注意网格项目的子元素不再是网格项目,举个🌰:

 

上面示例中container元素就是网格容器,item元素就是网格项目,注意item里的span元素并不是网格项目,不受Grid 网格布局的影响。

3、网格轨道(Grid Track)

关于网格布局可以直接想象成一个网格,而网格轨道就是这个网格中的“行”和“列”。

4、网格线(Grid Line)

划分网格的线,称为”网格线”(grid line)。水平网格线(column grid lines)划分出行,垂直网格线(row grid lines)划分出列。一个m * n的网格有m+1根水平网格线,n+1根垂直网格线。

5、单元格(Grid cell)

网格系统的最小单元,行和列的交叉区域,一个 m * n 的网格有 m * n 个单元格。

6、网格区域(Grid Area)

一个 网格区域可以由任意数量的网格单元格组成,如下图所示:

橙色边框包围内容就是一个网格区域。

二、网格容器属性

1、display属性

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

属性值:

  • grid: 生成块级网格
  • inline-grid: 生成内联网格
  • subgrid: 生成一个继承其父级网格容器的行和列的大小的网格容器,它是其父级网格容器的一个子项

注意:设为网格布局以后,容器子元素(项目)的float、display: inline-block、display: table-cell、vertical-align 和 column-* 等设置都将失效。

2、grid-template-columns,grid-template-rows属性

容器指定了网格布局以后,接着就要定义网格轨道,即划分行和列。grid-template-columns属性定义每一列的列宽,grid-template-rows属性定义每一行的行高。

用法:

grid-template-columns:  ... |   ... ;grid-template-rows:  ... |   ... ; 

属性值:

  • track-size: 网格轨道大小,可以使用css长度,百分比或用分数(用fr单位)。
  • line-name: (可选)使用方括号来指定网格线名字,方便以后的引用,网格布局允许同一根网格线有多个名字。
2.1、网格线的名称

如果没有直接指定网格线的名称网格线会自动分配正数和负数名称。示例:

Grid 网格布局 .container {margin: 20px;display: grid;grid-template-columns: 50px 50px 50px;grid-template-rows: 50px 50px 50px; } .item { text-align: center;border: 1px solid gray; }  1 2 3 4 5 6 7 8 9 

页面效果:

网格线名称如上图所示。

我们也可以直接给网格线定义名字,示例:

.container{display:grid;grid-template-columns: [col1-start] 50px [col1-end col2-start] 50px [col2-end col3-start] 50px [col3-end];grid-template-rows: [row1-start] 50px [row1-end row2-start] 50px [row2-end row3-start] 50px [row3-end] ;} 

其中有的网格线就不止一个名字,例如[col1-end col2-start]。

2.2、repeat()

有时候,重复写同样的值非常麻烦,尤其网格很多时。这时,可以使用repeat()函数,简化重复的值。

用法:

repeat (m , n) 

参数: m: 重复的次数 n: 重复的值

上面的示例代码用repeat方法可以改写成:

.container {display: grid;grid-template-columns: repeat(3, 50px);grid-template-rows: repeat(3, 50px);} 

repeat()重复某种模式也是可以的,示例:

.container {display: grid;grid-template-columns: repeat(2, 100px 20px 80px);} 

页面效果:

2.3、auto关键字

当你设置行或列大小为auto时,浏览器为自动为网格分配空间,示例:

.container {display: grid;grid-template-columns: 50px auto 50px;grid-template-rows: 50px auto 50px;} 

页面效果:

可以清晰地看到第二列的宽度基本上等于该列单元格的最大宽度,除非单元格内容设置了min-width且值大于最大宽度。

第二行的高度表现出了“包裹性”,即由内部文本或子元素决定高度。

2.4、auto-fill 关键字

有时,单元格的大小是固定的,但是容器的大小不确定。如果希望每一行(或每一列)容纳尽可能多的单元格,这时可以使用auto-fill关键字表示自动填充。

.container {display: grid;grid-template-columns: repeat(auto-fill, 150px);} 

页面效果:

在浏览器窗口缩放的情况下:

在浏览器窗口全屏的情况下&