CSS中Grid网格布局常用属性总结

2,359 阅读9分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第6天,点击查看活动详情

介绍

Grid布局网格布局可以将一个页面的div或其他html标签划分为几个主要区域,并且配置这些区域的大小、位置等关系。

Grid布局能够按行或列来对齐元素。可以给网格容器网格单元添加一些属性来控制元素的显示位置。网格单元还可以自己定位,像 CSS 定位的元素一样有重叠和层次。

一些概念

捕获.PNG

如图所示,画出了 Grid布局 的一些重要元素:

  • 网格容器:使用了网格布局的区域,图中灰色背景的区域。
  • 网格单元:是在一个网格元素中最小的单位,图中标记了的9个元素。
  • 行和列:水平分布的区域是行,垂直分布的区域是列。
  • 网格线:图中标记的红色的线(当然它不会超过网格容器,这么画出来看着明显一点)。3 * 3的网格,水平方向和垂直方向的网格线都有4条。
  • 网格间距:网格单元间的距离,分为横向间距和纵向间距。

Grid的属性包含 网格容器的属性 和 网格单元的属性,可以分别设置。这些属性也是下文的主要内容。

与flex布局的区别

flex弹性盒布局 是一维布局,盒子里面的元素只能沿横向或纵向排列。而 Grid网格布局 是二维布局,可以同时沿着横向和纵向设置排列。Grid网格布局的功能要比flex弹性盒布局的功能强大很多。

兼容性

捕获.PNG

上面所列的一些可以兼容Grid布局的主流浏览器的最低版本都是在2017年发布的,现在快到2023年了,所以也可以说目前Grid布局能够兼容大多数主流浏览器。

属性

先设置一个固定宽高的容器:

  <div class="container">
    <div class="i1">1</div>
    <div class="i2">2</div>
    <div class="i3">3</div>
    <div class="i4">4</div>
    <div class="i5">5</div>
    <div class="i6">6</div>
    <div class="i7">7</div>
    <div class="i8">8</div>
    <div class="i9">9</div>
  </div>
.container {
  width: 400px; 
  height: 400px;
  background-color: #ccc;
}

Grid布局的属性分为容器属性和网格单元属性

网格容器属性

display属性

容器设置 display 属性,属性值为 grid,该容器就是 Grid 布局。

  display: grid;

属性值可能是:

  • grid: 将容器设置为 grid 布局,当前元素是 块级元素属性。
  • inline-grid: 将容器设置为 grid 布局,当前元素是 行内元素属性。

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

grid-template-columnsgrid-template-rows 两个属性用来划分行和列。grid-template-columns属性定义每一列的列宽,grid-template-rows属性定义每一行的行高。

将容器内的9个元素分为三行三列,固定宽高为100px:

.container {
  grid-template-columns: 100px 100px 100px;
  grid-template-rows: 100px 100px 100px;
}

再为每个网格单元设置上背景色,在浏览器查看:

捕获.PNG

那如果做一个10行10列的表格,还要写10个属性值吗?当然不是,可以用 repeat 方法。

repeat()

repeat()接收两个参数,第一个是要重复的次数,第二个是要重复的值。所以上面的代码也可以替换为:

  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);

效果是一样的。

auto

auto 属性值自动为网格单元分配宽度和高度,占满容器。

  grid-template-columns: 100px auto 100px;
  grid-template-rows: 100px auto 100px;

捕获.PNG

不设置默认的宽度和高度,全都交给 Grid 布局自动分配:

  grid-template-columns: auto auto auto;
  grid-template-rows: auto auto auto;

捕获.PNG

auto-fill

单元大小固定,容器宽度不固定时,可以使用 auto-fill,此时单元格会自动填充到一行,如果宽度不够会自动换行。

  grid-template-columns: repeat(auto-fill, 100px);
  /* grid-template-rows: repeat(auto-fill, 100px); */

捕获.PNG

fr关键字

按照剩余空间的比例来分配单元所占的宽度或高度。

grid-template-columns: 100px 1fr 2fr;
/* grid-template-rows: 100px 1fr 2fr; */

捕获.PNG

上图第三列的宽度是第二列的2倍。

grid-template-columns: 1fr 3fr;

分成两列,第一列和第二列的宽度比为 1:3,如下图:

捕获.PNG

网格线名称

将网页运行在 Chrome 浏览器中,在控制台中选中 Grid 网格布局的标签,网页中就会显示出网格线,如下图:

捕获.PNG

自定义网格线的名称:

  grid-template-columns: [c1] 100px [c2] 100px [c3] 100px [c4];
  grid-template-rows: [r1] 100px [r2] 100px [r3] 100px [r4];

自定义名称方便以后的使用。

间距属性

  • grid-row-gap 行间距
  • grid-column-gap 列间距
  • grid-gap 上面两种属性合并的简写

设置单元间距:

  grid-row-gap: 10px;
  grid-column-gap: 10px;

等价于:

grid-gap: 10px 10px;

捕获.PNG

模板区域

Grid布局可以利用模板区域来定位网格单元,使用grid-template-areas属性用于定义区域。用区域名连接起来的区域必须是矩形的,目前还不能创建 L 形的区域。

  grid-template-areas: "a a a"
                       "b b b"
                       "c c c";

将九宫格的第一行标记为 a 区域,第二行为 b 区域,第三行为 c 区域。

某些区域不需要使用,可以用 . 表示。

  grid-template-areas: ". title ."
                       "side main main"
                       "side main main";

区域的命名会影响到网格线。每个区域的起始网格线,会自动命名为区域名-start,终止网格线自动命名为区域名-end

流向顺序

  • 属性:grid-auto-flow
  • 属性值:
    • row 默认值,行优先
    • column 根据自动布局算法,网格流向列优先,先填充列
    • dense 在上面属性的基础上,添加dense关键字,自动布局算法会寻找之前遗留的空隙,如果后面的元素能放的下,就把这个元素填充到空隙中,让布局更加紧密。
grid-auto-flow: column;

捕获.PNG

通过上面截图单元格中的数字可以看出,网格变为纵向排列。

.i5{
  /* 网格单元属性 - 线编号定位元素,下面会说到 */
  grid-column-start: 1;
  grid-column-end: 3;
}

class = i5的元素单独定位,如下图:

捕获.PNG

单元4后面留出了空隙,这种情况就可以使用dense自动填充。

grid-auto-flow: row dense;

捕获.PNG

可以看到单元6和单元7被填充到了空隙中。

网格单元内容的位置

设置单元格内容位于单元格中的位置,可以使用的属性有:justify-items属性设置单元格内容的水平位置,align-items属性设置单元格内容的垂直位置,place-items属性是前面两个属性合并的简写。

两个属性的属性值是一样的,可能是:

  • stretch:默认值,占满单元格
  • start:单元格的开始位置
  • end:单元格的结束位置
  • center:单元格内部居中

设置单元格内容位于单元格的右上角:

  justify-items: end;
  align-items: start;

捕获.PNG

设置水平和垂直方向都居中:

  justify-items: center;
  align-items: center;
  /* 简写等效于 */
  /* place-items: center center; */

捕获.PNG

上面两张图可以看到,设置了 justify-itemsalign-items属性后,单元格内容不再默认占满单元格了,可以单独设置单元格内容的宽高:

.i5{
  width: 100px;
  height: 100px;
  text-align: center;
  line-height: 100px;
}

捕获.PNG

网格容器的对齐方式

上面的例子,九宫格一直在类名为container的灰色背景容器的左上角,设置整个网格区域的位置,可以用到的属性有:justify-content属性是整个内容区域在容器里面的水平位置,align-content属性是整个内容区域的垂直位置,place-content属性是上述两个属性的合并简写。

属性值:

  • stretch:默认值,网格单元没有设置大小的情况下,占满整个容器
  • start:容器的开始位置
  • end:容器的结束位置
  • center:容器内部居中
  • space-around:每个网格单元两侧的间隔相等
  • space-between:(两端对齐)单元之间的间隔相等,与容器之间没有间隔
  • space-evenly:(均匀分布)单元与单元、单元与容器的间隔都相等

举例:把网格放到容器的右下角

  justify-content: right;
  align-content: end;

捕获.PNG

举例:居中

  justify-content: center;
  align-content: center;

捕获.PNG

举例:两端对齐并垂直居中

  justify-content: space-between;
  align-content: center;

捕获.PNG

上面的网格容器属性,都是定义在.container样式类中的。下文的网格单元属性,是定义在容器里面的网格单元的样式中。

网格单元属性

设置网格单元的位置

基于网格线设置位置

属性:

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

属性值:属性值是网格线的名称。

简写:grid-column-start和 grid-column-end 属性可以合并为 grid-column grid-row-start 和 grid-row-end则合并为 grid-row

指定网格单元位置,示例:

.i1 {
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 1;
  grid-row-end: 4;
}
.i2 {
  grid-column-start: 2;
  grid-column-end: 4;
}

捕获.PNG

如果设置了网格线的名称,也可以利用网格线别名指定位置,示例:

.container {
  grid-template-columns: [c1] 100px [c2] 100px [c3] 100px [c4];
  grid-template-rows: [r1] 100px [r2] 100px [r3] 100px [r4];
}
.i1 {
  grid-column: c1 / c4;
}

捕获.PNG

基于网格区域设置位置

grid-area属性指定网格单元放在哪一个区域。参数值是区域名称。

.container {
  grid-template-areas: "a a rig"
                       "b b rig"
                       "c c rig";
}
.i1 {
  grid-area: rig;
}

捕获.PNG

网格单元的对齐方式

针对独立的网格单元设置对齐方式。justify-self属性设置单元格内容的水平位置,align-self属性设置单元格内容的垂直位置,place-self属性以上两个属性的合并简写。

属性值:

  • stretch:默认值,网格单元没有设置大小的情况下,占满整个容器
  • start:容器的开始位置
  • end:容器的结束位置
  • center:容器内部居中

示例:让第一个单元格内容居中

.i1 {
  justify-self: center;
  align-self: center;
}

捕获.PNG

示例:让最后一个单元格内容在右下角

.i9 {
  /* 先垂直方向,后水平方向 */
  place-self: start end;
}

捕获.PNG

本文颜色样式代码

.i1 {
  background-color: #F8D800;
}
.i2 {
  background-color: #0396FF;
}
.i3 {
  background-color: #EA5455;
}
.i4 {
  background-color: #7367F0;
}
.i5 {
  background-color: #32CCBC;
}
.i6 {
  background-color: #F6416C;
}
.i7 {
  background-color: #28C76F;
}
.i8 {
  background-color: #9F44D3;
}
.i9 {
  background-color: #623AA2;
}