前言
在上一篇文章中,我们了解了 Flex 布局系统的强大功能和灵活性,其能够帮我们轻松地控制和对齐页面中的元素
然而,在实际的网页设计中,我们经常会遇到更加复杂的布局需求,例如创建多列、多行的网格结构,为了解决这些需求, Grid 布局应运而生
Grid 布局是一种 二维 布局系统,它不仅能够像 Flex 一样处理单轴上的布局,还能同时处理 行和列 ,从而实现更加复杂和精确的布局控制,无论是简单的页面排版,还是复杂的网页设计, Grid 布局都能提供强大的支持
Grid布局
Grid 布局,也称 网格布局 ,不同于 Flex 针对轴线的 一维布局 , Grid 是一个 二维 的布局,其将 项目 划分在 行 和 列 中, 容器 就像一个 网格 一样, 项目 就是一个个单元格,其能实现实现更加精细和复杂的设计
Grid 布局是由W3C在 2011 年首次提出的,于 2014 年,发布了关于首个工作草案
到 2016 年, Grid 布局规范进入候选推荐阶段,最终在 2017 年,正式成为W3C推荐标准,并在主流浏览器中得到了广泛支持
其兼容性如下(主流浏览器均已支持):
基本概念
任何元素均可定义为 Grid 容器,使用 Grid布局 ,只需设置元素的 display 属性为 grid 或 inline-grid 即可,如下:
定义了 Grid 布局的元素,称为 容器 (container),其直接子元素会自动按 网格 排列,称为 项目 (item)
注意,设Grid后,容器内项目的float、display: inline-block、display: table-cell、vertical-align和column-*等设置都将失效
行和列
容器 内水平区域称为 行 ,垂直区域称为 列
行 与 列 交叉的区域称为 单元格 , 项目 就按顺序存放在一个个单元格内
网格线
划分单元格的线称为 网格线 ,水平的网格线划分 行 ,垂直的网格线划分 列
区域
由一个或多个 项目 组成的矩形区域称为 Grid区域 (grid areas)
容器属性
下列属性主要使用于 容器 上
grid-template-rows|columns
该属性主要用于定义 网格 的 行 和 列 (几行,各行宽;几列,各列宽等)
其是 grid-template-rows 和 grid-template-columns 属性的简写形式,形式如下:
grid-template-rows 属性定义每一行的行宽, grid-template-columns 属性定义每一列的列宽
如下,定义一个3×3的 Grid容器 ,且每个 项目 的宽高均为 100px
有时,我们并不能确定某行(列)的宽度,或行(列)数量较多时,按这种形式写比较复杂,所以,CSS提供了一些 函数 或 关键字 ,可方便我们的设置
该 函数 用于 简化重复值 ,形式如下:
效果与上侧实现一致
repeat()接收两个参数,第一个参数表示 重复的次数 ,第二个参数表示 重复的内容
该 关键字 主要用于表示 比例 关系,其为 fraction (片段)的缩写
上侧container-1表示,将 容器 均分为三列,container-2表示,将 容器 按1:2:3的比例分为三列
该 函数 用于表示一个 长度范围 ,其接收两个参数:一个最小值(min)和一个最大值(max),表示长度在 [min, max] 内,数值是任何有效的CSS长度值、百分比或 auto
上侧代码表示将 容器 分为三列,左右两列固定宽度,中间的列最小宽度不小于 72px ,最大宽度不大于 1fr
该 关键字 表示由浏览器自己决定长度
上侧代码中,第一列会占据 容器 剩余宽度,除非列内单元格内容设置了 min-width ,且这个值大于最大宽度
该 关键字 用于实现 自动填充 ,有时候, 项目 (单元格)的大小是确定的,但 容器 的大小不确定,因此我们无法确定每一行(列)可容纳的 项目数 ,此时,我们希望每一行(列)可以尽可能多地容纳 项目 ,即可用 auto-fill
上侧的代码,我们对 列 设置了 auto-fill ,此时 容器 会按每列 100px 的宽度,自动填充列,直到不可容下更多 列 为止
与 auto-fill 类似的,还有一个 auto-fit 关键字
auto-fill与auto-fit的区别:
auto-fill会在 容器 中尽可能多地填充列或行,不管 单元格 是否有内容
其 特点 为:
自动填充列或行,尽量多地创建网格轨道
即使某些网格单元没有内容,也会分配空间
auto-fit当 容器 宽度增加时,会调整现有列的大小,而不是增加新的空列
其 特点 为:
自动适应列或行,现有列会根据容器大小调整
空列会被折叠,不占用额外的空间
一般情况下,两种基本无差别,只有当 容器 足够宽,足以在一行容纳所有 单元格 ,并且单元格宽度 不固定 ,才会有差异
举个栗子
当 容器 宽度足够富余时,fill 容器 会尽可能多地容纳列,每列100px,而fit容器会优先分配空间给已有列,每列 1fr
在 Grid 布局内,允许指定每一根网格线的名字,方便以后的引用
主要方式为使用 方括号 ,在 grid-template-columns 属性和 grid-template-rows 属性里面定义,如:
上侧代码中,定义了一个 3×3 的网格,所以有 4 根列线与 4 根行线,上侧的[]内的值即为每根线的名称,如: c1
同一根线可以有多个名称,只需定义在同一个 方括号 内,用 空格 隔开,如: [c1 column1]
gap
该属性用于定义 行与行 之间、 列与列 之间的 间距 ,是 row-gap 和 column-gap 的简写,形式如下:
接收一个或两个值,当只有一个时,表示行列间距均为该值
row-gap 属性用于设置 行与行 之间的间距
column-gap 属性用于设置 列与列 之间的间距
上侧代码大致效果如下(橙色部分即为间距):
过去的 gap 名称为 grid-gap ,该名称首次于 2017 年在 CSS Grid Layout Module Level 1 中被引入,但在 2018 年提出的 CSS Box Alignment Module Level 3 被重命名为 gap ,同时适用于Grid和Flex
grid-template-areas
该属性用于定义 网格区域 ,对网格区域进行 命名 ,后续可使用命名的网格区域进行布局,如:
上侧代码定义了一个 3×3 的网格,共有 9 个单元格,分别命名为 a-i ,共有 9 个区域
一个区域,可以由 一个或多个 单元格组成,当有多个单元格时,则用相同名称即可,如:
相同名称的单元格会合并为一个区域
如某些单元格不想命名,无需利用处理,用.点占位即可,如:
上侧的代码命名了 4 个区域,中间的点表示该单元格不属于任何区域
使用场景
简单直观地定义一个页面的布局
当你使用 grid-template-areas 定义网格区域时,Grid会自动生成与这些区域名称相关的命名网格线
命名网格线的格式如下:
area-name-start:区域的起始线
area-name-end:区域的结束线
例如,如果定义了一个名为 header 的区域,会自动生成以下网格线:
header-start
header-end
grid-auto-flow
该属性用于定义自动放置的 项目 的布局顺序,其决定了当 容器 中的 项目 没有明确指定位置时,浏览器如何自动放置它们,其可能值为:
row 的放置顺序是 先行后列 ,即先放满第一行,再放第二行,效果如下:
column 的放置顺序是 先列后行 ,即先放满第一列,再放第二列,效果如下:
dense 用于与 row 或 column 搭配使用,使 容器 更 紧凑 地排列 项目
如下,为无 dense 情况下的排列情况,会存在一些空白没有利用:
当搭配 dense 后,空白会被尽可能地利用,情况如下:
*-items
justify-items 属性设置单元格内 项目 的水平对齐效果(左中右)
align-items 属性设置单元格内 项目 的垂直对齐效果(上中下)
两个属性均有如下取值:
语法如下:
place-items 属性是 align-items 属性和 justify-items 属性的合并简写形式,形式如下:
接收两个值,用空格隔开,第二个值可省略,如省略,则表示与第一个值相同
*-content
justify-content 属性用于控制整个内容区域在 容器 内的水平对齐(左中右)
align-content 属性用于控制整个内容区域在 容器 内的垂直对齐(上中下)
两个属性取值均相同,如下:
place-content 属性是 align-content 属性和 justify-content 属性的合并简写形式,语法如下:
如果省略第二个值,则会假定第二个值与第一个值相同
grid-auto-*
grid-auto-columns 和 grid-auto-rows 用于定义在 Grid 布局中隐式创建的列和行的大小
其语法如下:
<track-size> 可以是任何有效的 CSS 尺寸值,如 px 、 % 、 fr 、 auto 等
举个栗子
比如,我们创建了一个 3×3 的网格 容器 ,但我们的 项目 不止 9 个(比如有 11 个),或者有些项目指定位置超出 3×3 的范围(比如设置在 (4, 2) 位置),此时,浏览器会自动生成多余的网格,用于放置 项目
在上侧代码中,任何隐式创建的行(即超过显式定义的三行的行)将被设置为 50px 高
grid-template
该属性是 grid-template-rows 、 grid-template-columns 和 grid-template-areas 的合并简写形式
举个栗子
grid
grid 是 grid-template-rows 、 grid-template-columns 、 grid-template-areas 、 grid-auto-rows 、 grid-auto-columns 、 grid-auto-flow 六个属性的合并简写形式
基本语法
简写形式可以简化书写,但同时也降低了代码可读性,不建议使用
项目属性
主要作用域 项目 上的属性
grid-column|row
grid-column 是一个简写属性,用于定义 项目 在网格中的水平位置,其结合了以下两个属性:
基本语法
<grid-line> 可以是行号、命名的网格线、 span 关键字加行数,或者 auto
<grid-area> 是通过 grid-template-areas 定义的网格区域名
grid-row 也是一个简写属性,用于定义 项目 在网格中的垂直位置,其结合了以下两个属性:
使用与 grid-column 一致
span 关键字,后接空格跟一个数字,表示跨越(占据)多少行(列)
grid-area
该属性用于指定 项目 放置在哪一区域
基本语法
<grid-area-name> 为 grid-template-areas 定义的区域名称
其还有另一种语法:
可用作 grid-row-start 、 grid-column-start 、 grid-row-end 、 grid-column-end 的合并简写形式
*-self
justify-self 属性用于设置 项目 在单元格内的水平对齐方式,跟 justify-items 属性的用法类似,但只作用于单个项目
align-self 属性用于设置网格项目在单元格内的垂直对齐方式,跟 align-items 属性的用法类似,但只作用于单个项目
两者可能取值均相同,如下:
place-self 是一个简写属性,用于同时设置 justify-self 和 align-self 的值,形式如下:
如果省略第二个值,则第二个值与第一个值相等
特点
二维布局系统 :支持同时定义行和列,适合复杂布局
显式与隐式网格 :可以明确定义网格,同时自动创建额外的网格以容纳项目
强大的对齐与定位控制 :通过属性如 justify-items 、 align-items 、 justify-content 和 align-content ,可以精确控制项目在网格中的位置和对齐方式
网格间距和分区 :支持定义网格之间的间距,并能够划分为命名的网格区域,便于布局管理和维护
响应式设计支持 :可以轻松地调整网格的大小和布局,以适应不同的屏幕尺寸和设备
配合 Flexbox 使用 :与 Flex 结合使用,可以实现更复杂的布局需求,灵活而强大
使用场景
复杂的布局需求 :适合需要精确控制多个项目在网格中位置和大小的复杂布局,如新闻网站的多栏布局或者仪表板的网格化布局
网格化设计 :对于需要将页面划分为多个命名区域并对其进行管理的设计,如大型网页或应用程序的板块化设计
响应式设计 :能够根据不同的屏幕尺寸和设备自动调整布局,使得设计在移动设备和桌面上都能够优雅地呈现
比如,哔哩哔哩推荐的视频列表就是用 grid 实现的, Grid 是一个非常强大的布局工具,特别适合于需要更高级和复杂布局需求的现代网页设计和开发