利用grid布局可以高效地实现二维布局。但是其众多的属性以及属性值,让很多刚刚接触的人和没有系统性总结的人云里雾里,这增加了使用grid的成本。

为此,从实用角度出发,按照类别,系统性地总结了日常开发常用的知识点。

网格容器属性

声明元素为网格布局

通过 display: grid 声明某个元素为网格布局:

.wrapper {
  /* 声明一个容器 */
  display: grid;
  /*  声明列的宽度  */
  grid-template-columns: repeat(3, 200px);
  /*  声明行间距和列间距  */
  gap: 20px;
  /*  声明行的高度  */
  grid-template-rows: 100px 200px;
}

grid-template-columns / grid-template-rows

grid-template-columns定义网格中 的宽度。grid-template-rows定义网格中 的宽度。

下面以 grid-template-columns 做说明(grid-template-rows 的用法与之类似,就不必重复说明了)

固定宽度

.wrapper {
  display: grid;
  /*  声明了三列,宽度分别为 200px 100px 200px */
  grid-template-columns: 200px 100px 200px;
  gap: 5px;
  /*  声明了两行,行高分别为 50px 50px  */
  grid-template-rows: 50px 50px;
}

repeat() 函数

简化重复的值。

语法:repeat(repeat_number, length)

.wrapper {
  display: grid;
  grid-template-columns: 200px 100px 200px;
  gap: 5px;
  /*  2行,而且行高都为 50px  */
  grid-template-rows: repeat(2, 50px);
}

auto-fill 关键字

表示自动填充,让一行(或者一列)中尽可能的容纳更多的单元格。

grid-template-columns: repeat(auto-fill, 200px) 表示列宽是 200 px,但列的数量是不固定的,只要浏览器能够容纳得下,就可以放置元素,代码以及效果如下图所示:

.wrapper {
  display: grid;
  grid-template-columns: repeat(auto-fill, 200px);
  gap: 5px;
  grid-auto-rows: 50px;
}

fr 关键字

fr 单位代表网格容器中可用空间的一个等份。grid-template-columns: 200px 1fr 2fr 表示第一个列宽设置为 200px,后面剩余的宽度分为两部分,宽度分别为剩余宽度的 1/3 和 2/3。代码以及效果如下图所示:

.wrapper {
  display: grid;
  grid-template-columns: 200px 1fr 2fr;
  gap: 5px;
  grid-auto-rows: 50px;
}

minmax() 函数

minmax() 函数产生一个长度范围,表示长度就在这个范围之中都可以应用到网格项目中。它接受两个参数,分别为最小值和最大值。grid-template-columns: 1fr 1fr minmax(300px, 2fr) 的意思是,第三个列宽最少也是要 300px,但是最大不能大于第一第二列宽的两倍。代码以及效果如下:

语法:minmax(min_length, max_length)

.wrapper {
  display: grid;
  grid-template-columns: 1fr 1fr minmax(300px, 2fr);
  gap: 5px;
  grid-auto-rows: 50px;
}

auto 关键字

由浏览器决定长度。通过 auto 关键字,可以轻易实现三列或者两列布局。grid-template-columns: 100px auto 100px 表示第一第三列为 100px,中间由浏览器决定长度,代码以及效果如下:

.wrapper {
  display: grid;
  grid-template-columns: 100px auto 100px;
  gap: 5px;
  grid-auto-rows: 50px;
}

gap / column-gap / row-gap

row-gap 属性设置行间距

column-gap 属性设置列间距

gap 属性是上面两者的简写形式:row-gap column-gap

.wrapper {
  display: grid;
  grid-template-columns: 200px 100px 100px;
  gap: 10px 20px;
  grid-auto-rows: 50px;
}

grid-auto-flow

默认的放置顺序是“先行后列“:先填满第一行,再开始放入第二行,即下图英文数字的顺序 one,two,three...。这个顺序由 grid-auto-flow 属性决定。

语法:

grid-auto-flow: row;            // 先行后列(默认值)
grid-auto-flow: column;         // 先列后行
grid-auto-flow: row dense;      // 先行后列,尽可能填满表格
grid-auto-flow: column dense;   // 先列后行,尽可能填满表格

grid-auto-flow: row

为了尽可能填满表格,使用 grid-auto-flow: row dense 可以填充上图中 ThreeSeven 之间的空白。效果如下所示:

.wrapper {
  display: grid;
  grid-template-columns: 100px 200px 100px;
  grid-auto-flow: row;
  /* grid-auto-flow: row dense; */
  gap: 5px;
  grid-auto-rows: 50px;
}

justify-items / align-items / place-items

justify-items 设置网格布局中,所有单元格内容的水平位置(左中右)。

align-items 设置网格布局中,所有单元格内容的垂直位置(上中下)。

place-items 属性是上面两者的简写形式:align-items justify-items

下面以 justify-items 做说明(align-items 的用法与之类似,就不必重复说明了)

语法:

justify-items: start;     // 单元格的起始边缘(水平 - 左边 / 垂直 - 上边)
justify-items: center;    // 单元格内部居中
justify-items: end;       // 单元格的结束边缘(水平 - 右边 / 垂直 - 下边)
justify-items: stretch;   // 默认值。占满单元格的某一维度的全部空间(水平 or 垂直)

justify-items: start - 单元格的起始边缘(水平 - 左边 / 垂直 - 上边):

justify-items: end - 单元格内部居中:

justify-items: center - 单元格的结束边缘(水平 - 右边 / 垂直 - 下边):

justify-items: stretch - 默认值。占满单元格的某一维度的全部空间(水平 or 垂直):

.wrapper {
  display: grid;
  grid-template-columns: 100px 200px 100px;
  gap: 5px;
  grid-auto-rows: 50px;
  justify-items: start;
}

grid-auto-columns / grid-auto-rows

grid-template-columnsgrid-template-rows 这两个属性构成了网格容器的行数列数

如果实际的单元格数量,超过了由 grid-template-columnsgrid-template-rows 构成的单元格数量,那么这些额外单元格行高列宽如何约定呢?

这就需要由 grid-auto-columns / grid-auto-rows 来确定了:

  • grid-auto-columns 确定额外单元格列宽(默认值为 auto,自动适配内容的最大宽度)
  • grid-auto-rows 确定额外单元格行高(默认值为 auto,自动适配内容的最大宽度)

grid-auto-flowrow 时,单元格按照 先行后列 顺序填充网格:额外单元格列宽grid-template-columns 确定;行高 就由 grid-auto-rows 确定。

.wrapper {
  margin: 50px;
  display: grid;
  grid-template-columns: 200px 100px;
  /*  只设置了两行,但实际的数量会超出两行,超出的行高会以 grid-auto-rows 算 */
  grid-template-rows: 100px 100px;
  grid-gap: 10px 20px;
  grid-auto-rows: 40px;
}

grid-auto-flowcolumn 时,单元格按照 先列后行 顺序填充网格:额外单元格行高grid-template-rows 确定;列宽 就由 grid-auto-columns 确定。

.wrapper {
  margin: 50px;
  display: grid;
  grid-template-columns: 200px 100px;
  grid-auto-flow: column;
  /*  只设置了两列,但实际的数量会超出两列,超出的列宽会以 grid-auto-columns 算 */
  grid-template-rows: 100px 100px;
  grid-gap: 10px 20px;
  grid-auto-columns: 80px;
}

网格项目属性

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

指定网格项目所在的四个边框,分别定位在哪根网格线,从而指定项目的位置。网格线的序号:

  • 从左到右,由 1 开始依次递增。
  • 从上到下,由 1 开始依次递增。

  • grid-column-start 属性:网格项目左边框所在的垂直网格线
  • grid-column-end 属性:网格项目右边框所在的垂直网格线
  • grid-row-start 属性:网格项目上边框所在的水平网格线
  • grid-row-end 属性:网格项目下边框所在的水平网格线

上图Five的样式:

.wrapper {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  grid-auto-rows: minmax(100px, auto);
}

.five {
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 2;
  grid-row-end: 5;
  background: #e6ceac;
}

span 关键字

上述四个属性的值还可以使用 span 关键字,表示"跨越",即左右边框(上下边框)之间跨越多少个网格。

.item-1 {
  grid-column-start: span 2;
}

上面代码表示,1 号项目的左边框距离右边框跨越 2 个网格。

justify-self / align-self / place-self

justify-self / align-self / place-selfjustify-items / align-items / place-items 属性的用法是一样的,只是 justify-self / align-self / place-self 作用于单个网格项目

日常使用注意事项

align-items默认值是stretch,会导致每个单元格 dom 元素的高度被撑满,不是 dom 元素原本的高度。为了使单元格 dom 元素的高度还原为实际的高度,建议在使用grid时,先进行如下的初始化:

.wrapper {
  display: grid;
  align-items: start;
}

参考

最强大的 CSS 布局 —— Grid 布局


Steven
33 声望3 粉丝