前言
本文先说明了为什么会有 grid 布局,简单介绍了 flex 布局和 grid 布局的区别,较为详细的介绍了 grid 布局的概念。
本文并不是大而全的文档,只能简单讲解 grid 布局的概念、特性与用法。具体属性可以查阅 MDN 文档。
为什么会有 grid 布局
flex 布局已经足够强大的,几乎你能见到的页面布局都可以使用 flex 布局实现,那为什么还需要 grid 布局呢?
很多时候,页面布局并不是一条线的流式布局,不是单一的从左到右,从上到下,flex 布局可以理解为单一方向上的布局,而 grid 布局可以直接实现二维上的布局。
flex 布局是简单实用的,而 grid 布局是强大灵活的。
大多数浏览器虽然已经支持了 grid 布局,但 grid 布局的兼容性并不如 flex 布局好。
grid 布局
MDN 中将 grid 布局翻译成网格布局,grid 布局确实如此。一个网格通常具有许多的列(column)与行(row),网格的间隙一般被称为沟槽(gutter)。根据网格,我们能在水平及垂直上将设计元素进行排列。
使用 grid 布局很简单,通常只有三步:声明 grid 容器、划分网格、放置元素。
我们可以使用 display:grid 或 inline-grid 声明一个 grid 容器,这与声明 flex 容器类似。
网格划分
在定义 grid 容器后,网页并不会马上发生变化,我们可以使用 grid-template 相关属性将容器划分为网格。
grid-template-rows:定义网格各行的高度。grid-template-columns:定义网格各列的宽度。fr:新单位,将可用(剩余)空间按比例分配。repeat()函数:简化重复数值,接收两个参数,一个是重复次数,第二个是重复的值。auto-fill关键字:自动填充,让一列/行中容纳尽可能多的格子。minmax()函数:定义最小与最大长/宽,接收两个参数,第一个是最小长/宽,第二个是最大长/宽。auto:由浏览器决定长/宽。
我们还可以使用 grid-row-gap 来定义行间距,使用 grid-column-gap 属性来定义列间距,使用 grid-gap 进行简写(先行后列)。
元素放置
划分网格后,我们可以设置每一个子项占哪些行或列,我们有两种元素放置方式
基于线的元素放置
网格中的第一条线是最左边和最上面的那条线(网格边缘线),顺序从左至右,从上至下。
但第一条线的起始点其实与文档书写模式相关。 对于阿拉伯语第一条列分隔线在网格的最右边,因为阿拉伯文是从右往左书写的。
我们可以在元素中使用以下属性对元素进行放置。
grid-row-start:grid-row-end:grid-column-start:grid-column-end:
start 与 end 属性决定了网格线的起始位置,四条网格线围成了我们想要放置的元素区域。
我们也可以用 -1 来定位到最后一条线,可以使用负数来指定倒数的某一条线。 但是这只能用于显式网格,对于隐式网格不一定生效。
我们可以使用 grid-row 对 grid-row-start 和 grid-row-end进行简写,grid-column 对 grid-column-start 和 grid-column-end进行简写,顺序都是先行后列,使用 / 隔开。
更近一步,我们可以使用 grid-area 属性进行简写,先行后列,先开始后结束,使用 / 隔开。
grid-area: row-start / column-start / row-end / column-end
几种简写均存在单值写法或多值语法,详细写法可以查询文档。
使用 grid-template-areas 属性放置元素
我们可以命名一些元素并在属性中使用这些名字作为一个区域。
.container {
display: grid;
grid-template-areas:
"header header"
"sidebar content"
"footer footer";
grid-template-columns: 1fr 3fr;
grid-gap: 20px;
}
我们定义了 header、sidebar、content、footer 区域并排列在 grid-template-areas 中,之后可以在元素中使用这些名字,并对应到想要的区域。
header {
grid-area: header;
}
article {
grid-area: content;
}
aside {
grid-area: sidebar;
}
footer {
grid-area: footer;
}
grid-template-areas 属性的使用规则如下:
- 你需要填满网格的每个格子
- 对于某个横跨多个格子的元素,重复写上那个元素
grid-area属性定义的区域名字 - 所有名字只能出现在一个连续的区域,不能在不同的位置出现
- 一个连续的区域必须是一个矩形
- 使用
.符号,让一个格子留空
隐式网格
显式网格包含了在 grid-template-columns 和 grid-template-rows 属性中定义的行和列。
如果你在显式网格定义之外又放了一些东西(内容超出显式网格,比如格子数量过多),网格将会在隐式网格中创建行和列。
隐式网格中生成的行/列大小是参数默认是 auto,大小会根据放入的内容自动调整。
我们可以设置 grid-auto-rows 属性和 grid-auto-columns 属性来定义隐式网格的长/宽,语法与 grid-template-columns 和 grid-template-rows 完全相同。
其他属性
grid 布局最基本的布局方式已经介绍完毕,但强大的 grid 布局仍然内置了多种属性以方便布局,鉴于本文只对 grid 布局进行最简单的概述,下面只对其他属性进行简单介绍,属性内容通常是符合直觉的,如果你了解 flex 布局,这些一定很容易理解,他们十分相似,但是 grid 布局更加复杂,详细可以查看文档。
以下属性可以在 grid 容器中使用。
grid-auto-flow:控制着自动布局算法怎样运作,精确指定在网格中被自动布局的元素怎样排列。justify-items:设置单元格内容的水平位置。align-items:设置单元格的垂直位置。justify-content:设置整个内容区域在容器中的水平位置。align-content:设置整个内容区域在容器中的垂直位置。
以下属性可以在 grid 元素(项目)中使用。
justify-self:设置单元格内容的水平位置。align-self:设置单元格内容的垂直位置。
参考资料
网格 - 学习 Web 开发 | MDN (mozilla.org)
最强大的 CSS 布局 —— Grid 布局 - 掘金