Grid布局是微软在2010年提出来的一种新的布局方式,到2016年的时候提交了该布局的草案,经过这三四年的发展,grid布局慢慢变的成熟,兼容性也越来越好,可以适当学起来用起来了

本次学习的几个点:

  • CSS布局发展过程
  • Grid布局的优点以及相关术语介绍
  • Grid布局的使用
  • 注意事项、备注
  • 参考资料

在我们开始学习前,先了解下它能用在什么情况下

例如这个页面就是用grid布局的:

Grid布局

网格

在了解和学习网格布局之前,我们先了解下什么是网格,网格是一组相交的水平和垂直线,它定义了网格的行和列

Grid 布局学习 - 掘金 - 图1

CSS布局发展过程

  • table 表格布局:table 比其他 html标记占更多的字节、布局比较死板不灵活、会阻挡浏览器渲染引擎的渲染顺序从而使得加载速度慢
  • float + position方式布局:使用 float 浮动和 position 定位去布局,float会使得元素脱离文档流,浮动高度塌陷,还需要额外的清除浮动解决这种高度塌陷、不易于垂直居中等问题
  • flexbox 弹性布局:一维布局,最适合应用于程序的组件和比较小规模的布局,比较好用而且支持性较好
  • grid 网格布局:二维布局,适用于大规模的布局

例如:下面这两种类型的布局就很适合用grid布局:

Grid 布局学习 - 掘金 - 图2

Grid 布局学习 - 掘金 - 图3

本人认为Grid布局的出现并不是要取代上面的几种布局方式,而且跟上面的几种方式一起结合使用,用更简洁的代码实现页面布局

Grid布局的优点

优势
  • 固定或弹性的轨道尺寸:可以给每个轨道设置固定的尺寸,也可以设置auto | 1fr | 10% 等弹性的尺寸,实际展示的轨道大小会随着父级的宽高变化而变化

  • 定位项目:可以给每个子项设置具体所占据的位置

  • 创建隐式的轨道:当子项设置的定位位置超出了父级设定的轨道大小,会创建隐式的轨道

  • 对齐控制:和flexbox一样,有多种对齐方式的控制

  • 控制重叠内容,直接在子项上设置z-index的值即可

兼容性

Grid 布局学习 - 掘金 - 图4

pc端的浏览器的兼容性还是不错的,IE10和11需要添加-ms-来实现兼容

移动端需要注意的是:ios10.3版本以下不支持,使用需斟酌或者做好兼容处理

Grid布局中的相关术语

  1. Grid Container : 网格容器,一个元素应用了 display: grid; 后就是一个网格容器了,它是所有网格项的父元素,例如下面的代码里<div class="grid"></div>就是网格容器
    // html


//css
.grid {
display: grid;
}
复制代码

  1. Grid item : 网格项,上面的 grid-item 就是网格子项

  2. Grid Line : 网格线,组成网格项的分界线,虚拟的,下图的3×4的网格里有4条水平网格线和5条垂直网格线

Grid 布局学习 - 掘金 - 图5

  1. Grid track : 轨道,网格轨道,两个相邻的网格线之间为网格轨道

如下图:共有7个网格轨道,水平方向3个网格轨道,垂直方向4个网格轨道

Grid 布局学习 - 掘金 - 图6

  1. Grid Cell : 网格单元,两个相邻的列网格线和两个相邻的行网格线组成的网格单元,网格项是HTML里的dom元素,而网格单元是定义网格容器的时候分割出来的网格单元

Grid 布局学习 - 掘金 - 图7

  1. Grid area: 网格区域: 四个网格线包围的总区域,与网格单元不同的是,网格单元必须是相邻的网格线

Grid 布局学习 - 掘金 - 图8

  1. 单位:fr 单位:剩余空间分配数,用于在一系列长度值中分配剩余空间,按数字比例分配

例如:

网格总宽度如果是600px,那么下面这种设置中,1fr = (600 - 50 - 150) * (1 / (1+3)) = 100px

  1. .grid {
  2. grid-template-columns: 50px 1fr 3fr 150px;
  3. }
  4. 复制代码

容器中的属性

查看练习demo

  1. display

它的值为:

  • display: grid;:设置为容器元素

Grid 布局学习 - 掘金 - 图9

  • display: inline-grid 设置为容器元素,且为行内网格

Grid 布局学习 - 掘金 - 图10

  • display: subgrid :如果网格容器本身是网格项,此属性用来继承父网格容器的列和行大小

它的兼容性很差,基本可以先不了解

Grid 布局学习 - 掘金 - 图11

  1. grid-template: 定义行与列的轨道大小,它是一个复合写法,具体属性包含了:
  • grid-template-rows: 水平方向划分行,值为每一行的高度,空格分隔
  • grid-template-columns: 垂直方向划分列,值为每一列的宽度,空格分隔
  • grid-template-areas: 网格划分区域,值为命名

语法:

  1. .container {
  2. grid-template-rows: <track-size> | <line-name> <track-size>;
  3. grid-template-columns: <track-size> | <line-name> <track-size>;
  4. grid-template-areas:
  5. <grid-area-name> | . | none
  6. <grid-area-name> | . | none
  7. }
  8. // 复合写法:
  9. .container {
  10. grid-template: <grid-template-rows> / <grid-template-columns>
  11. }
  12. 复制代码
  • <track-size>: 可以使用css的长度单位、百分比、auto或者一个新的单位fr 其中 auto 是用来表示剩下的长度 单位 fr :除去其他的设定的固定的宽度以外,剩下的按比例分,类似于flex中的flex: n;

  • <line-name>: 可以给每条网格线设置名称 [任何名称]

  • <grid-area-name> : 区域名称 “任何名称”
    .container {
    grid-template-rows: [第一条行线] 25% 100px auto;
    grid-template-columns: [第一条列线] 100px 20px auto 40px;
    }
    复制代码

表现为如下:

Grid 布局学习 - 掘金 - 图12

grid-template-areas: 设置区域名称的

Grid 布局学习 - 掘金 - 图13

  1. grid-gap :行和列之间的间隔宽度 , 它是两个属性的复合写法
  • grid-gap-rows: 行与行之间的间隔

  • grid-gap-columns: 列与列之间的间隔
    .container {
    grid-gap-rows: 20px;
    grid-gap-columns: 10px;
    }
    // 复合写法:
    .container {
    grid-gap: 20px 10px;
    }
    复制代码

  1. place-items : 每个单元格内部的水平垂直对齐方式的复合写法
  • justify-items: 水平方向对齐方式
  • align-items: 垂直方向对齐方式

两个属性的值都有以下几种

  • stretch : 默认值,水平|垂直 内容拉伸填充
  • start: 水平|垂直 (宽度|高度)收缩为内容大小,(左侧|上侧)对齐
  • end:水平|垂直 (宽度|高度)收缩为内容大小,(右侧|下侧)对齐
  • center:水平|垂直 (宽度|高度)收缩为内容大小,居中对齐
  1. .container {
  2. place-items: <align-items> / <justify-items>;
  3. }
  4. 复制代码
  1. place-content: 以下两个属性的复合写法,是表示网络单元的水平布局方式
  • justify-content: 仅在网格总宽度小于grid容器宽度时候有效果

值分为以下几种:

  • stretch:拉伸,宽度填满grid容器,需要定的网格尺寸为auto的时候有效,如果定死宽度则无法拉伸
  • start:左对齐
  • end:右对齐
  • center:居中对齐
  • space-between:两端对齐
  • space-around: 每个grid子项两侧都环绕互不干扰的等宽的空白间距,最终视觉上边缘两侧的空白只有中间空白宽度一半
  • space-evenly:每个grid子项两侧空白间距完全相等
  • align-content: 网络元素的垂直方向布局方式, 如果grid子项只有一行则不生效,它的值同上
  1. grid-auto: 以下三个属性的复合写法

grid-auto的相关demo

  • grid-auto-rows:网格项目多余设置的单元格,会创建隐式轨道

  • grid-auto-columns:网格项目多余设置的单元格,会创建隐式轨道
    .container {
    grid-auto-rows: 100px;
    grid-auto-columns: 70px;
    }
    复制代码

  • grid-auto-flow: 控制没有明确指定位置的grid子项的放置方式

值分为以下几种:

  • row: 默认值,没有指定位置的网格按顺序水平方向排列
  • column: 没有指定位置的网格垂直顺序排列
  • row dense:自动排列启动密集排序,水平方向
  • column dense:自动排列启动密集排序,垂直方向

看示例 demo

  1. grid: 以下几个属性的复合写法:
  • grid-template-rows
  • grid-template-columns
  • grid-template-areas
  • grid-auto-rows
  • grid-auto-columns
  • grid-auto-flow

具体设置值如下:

  1. 1.grid:none:所有子属性都是初始化的值
  2. 2.grid: <grid-template>
  3. 3.grid: <grid-template-rows> / [ auto-flow && dense? ] <grid-auto-columns>?
  4. 4.grid: auto-flow & dense ? <grid-auto-rows> ? / <grid-template-columns>
  5. 复制代码

auto-flow: 表示的值为 row | column,但是统一使用 auto-flow来表示,具体需要看它放置的位置在哪里,如果放置在 / 的左侧,就表示 grid-auto-flow: row, 如果放在右侧,就表示 grid-auto-flow: column

  1. grid: 100px 60px / 1fr 2fr
  2. 相当于:
  3. grid-template-rows: 100px 60px;
  4. grid-template-columns: 1fr 2fr;
  5. 3.grid: 100px 60px / auto-flow 1fr 2fr
  6. 相当于:
  7. grid-template-rows: 100px 60px;
  8. grid-auto-columns: 1fr 2fr;
  9. grid-auto-flow: column
  10. 4.grid: auto-flow dense 100px 60px / 1fr 2fr;
  11. 相当于:
  12. grid-auto-rows: 100px 60px
  13. grid-template-columns: 1fr 2fr;
  14. grid-auto-flow: row dense
  15. 复制代码

使用grid复合写法的例子: grid复合写法demo

以上属性都是外层容器属性的值

作用在容器子项上的属性

操作demo

  1. grid-column: 以下两个属性的复合写法
  • grid-column-start

  • grid-column-end
    .item {
    grid-column-start: | | span | span
    grid-column:
    }
    复制代码

值的含义:

<name>自定义网格线的名称

<number> 从第几条网格线开始

span <name> 当前网格会自动扩充,直到命中指定的网格线名称

span <number> 当前网格会自动跨越指定的网格数量

auto 全自动,包括定位和跨度

例如:下图中的item-a定义了它从第一条水平方向的网格线到第三条水平方向的网格线,从第2条垂直网格线到第3条垂直网格线,也就是占据了第1、2行第2列

Grid 布局学习 - 掘金 - 图14

  1. grid-row: 以下两个属性的复合写法
  • grid-row-start

  • grid-row-end
    .item {
    grid-row-start: | | span | span
    grid-row:
    }
    复制代码

  1. grid-area: 当前网格所占区域,使用grid-template-areas自定义网络区域,使用grid-area让grid子项指定这些使用区域,就自动进行了区域分布 例如:
    grid-area:
    区域名称,由容器属性grid-template-area创建
    / / / 占据网格区域的纵横起始位置
    复制代码

  2. justify-self: 单个网格元素的水平对齐方式

值分为以下几种:

  • stretch(默认):拉伸,水平填充
  • start 水平尺寸收缩为内容大小,沿着网格线左侧对齐
  • end 水平尺寸收缩为内容大小, 沿着网格线右侧对齐
  • center 水平尺寸收缩为内容大小,当前区域内部水平居中对齐显示
  1. align-self: 单个网格元素的垂直对齐方式 例如:
  • stretch(默认):拉伸,垂直填充
  • start 垂直尺寸收缩为内容大小,沿着网格线上侧对齐
  • end 垂直尺寸收缩为内容大小, 沿着网格线下侧对齐
  • center 垂直尺寸收缩为内容大小,当前区域内部垂直居中对齐显示

以上两个属性可以使用 place-self 去写 place-items:<align-self> / <justify-self>

grid布局中的css函数

查看css函数的相关demo

  1. repeat(): 跟踪列表的重复片段,允许大量重复显示模式的行或列以以更紧凑的方式编写

可用范围:grid-template-columnsgrid-template-rows

语法: repeat(<repeat>, <value>)

<repeat>: 取值有以下几种:

  1. 1. 整数,确定确切的重复次数
  2. 2. `<auto-fill>`: 以网格项为准自动填充,需要结合minmax()函数来使用
  3. 3. `<auto-fit>` : 以网格容器为准自动填充,需要结合minmax()函数来使用
  4. 复制代码

<value>: 取值有以下几种:

  1. 1. 固定长度
  2. 2. 百分比
  3. 3. fr单位
  4. 4. max-content: 表示网格的轨道长度自适应内容最大的那个单元格
  5. 5. min-content:表示网格的轨道长度自适应内容最小的那个单元格
  6. 6. auto:不推荐使用
  7. 复制代码

可以多次使用

grid-template-columns: 20px auto repeat(3, 1fr) 40px

  1. fit-content():参数是长度值或百分比

公式:min(maximum size, max(minimum size, argument))

它在内容的最小值和参数中取一个最大值,然后再在内容的最大值中取一个最小值

当内容少时,它取内容的长度,如果内容多,内容长度大于参数长度时,它取参数长度,可以理解为它可以控制最大值是多少

  1. minmax(min, max) :定义了长度范围区间

取值:

  1. 1. 固定长度
  2. 2. 百分比
  3. 3. fr单位
  4. 4. max-content: 表示网格的轨道长度自适应内容最大的那个单元格
  5. 5. min-content:表示网格的轨道长度自适应内容最小的那个单元格
  6. 6. auto:不推荐使用
  7. 复制代码

注意事项

  • 当元素设置了网格布局,column、float、clear、vertical-align属性无效
  • grid布局是二维布局,适合布局整体

一个grid的demo

参考资料

张鑫旭空间:grid布局

MDN:grid

阮一峰:CSS Grid 网格布局教程