1. 什么是 Grid 布局
Grid(网格布局)定义了网格的行和列,我们可以将网格元素放置在与这些行和列相关的位置上,做出多种布局。
2. 为什么学习 CSS Grid 布局
Grid 能够定义行和列来进行二维布局,并且简便、灵活。
免去了 Bootstrap 等 CSS 框架的使用。
主流浏览器都比较支持。
3. 开始
3.1 第一个网格
定义六个 div 用于布局(相关颜色等 css 代码已省略),默认情况下每个 div 占满一行。
<div class="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
最开始,用 display: grid;
来创建一个网格容器 (Grid Container),其中的子网格称为 Grid items。下边创建一个三列两行的网格。
.container {
display: grid;
/* 3 列, 宽度分别为 100px, auto, 200px */
grid-template-columns: 100px auto 200px;
/* 2 行, 高度分别为 50px, 50px */
grid-template-rows: 50px 50px;
/* 行间距 列间距 */
gap: 5px 20px;
}
具体效果:
3.2 fr and repeat
fr
使用 fr 能够将剩余的空间进行一定比例的分配。
用 fr 制作一个两行三列,并且三列的宽度相等的网格。
.container {
display: grid;
/* 三个等宽的列 */
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 50px 50px;
gap: 5px 20px;
}
进行如下修改,将第一列的宽度固定为 100px,则其他两列会按照剩余空间进行 1:1分配。
grid-template-columns: 100px 1fr 1fr;
试下 2fr,可以看到 2fr 列是 1fr 列的两倍。
grid-template-columns: 100px 1fr 2fr;
repeat
可以用 repeat 重复创建相同的行或者列。
.container {
display: grid;
/* 三个等宽的列 */
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 50px 50px;
gap: 5px 20px;
}
/* 用 repeat */
.container {
display: grid;
/* repeat(数量, 长度) */
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 50px);
gap: 5px 20px;
}
/* 简写 */
.container {
display: grid;
/* grid-template: 行 / 列; */
/* grid-template: 50px 50px / 1fr 1fr 1fr; 与下边代码效果相同 */
grid-template: repeat(2, 50px) / repeat(3, 1fr);
gap: 5px 20px;
}
4. 定位与布局
4.1 Grid items 的定位
如下,我们创建的 container 里的 4 个 div 色块即为 Grid items(子网格),接下来要对他们进行定位。
<div class="container">
<div class="header">HEADER</div>
<div class="menu">MENU</div>
<div class="content">CONTENT</div>
<div class="footer">FOOTER</div>
</div>
先创建网格容器。
.container {
display: grid;
gap: 3px;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: 40px 200px 40px;
}
给子网格 header 设置 grid-column: 1 / 3;
,表示 header 的列在网格线 1 和网格线 3 之间,即占了两列。
.header {
grid-column: 1 / 3;
}
通过浏览器开发者工具 (F12/Ctrl+shift+I) 可以看到,网格线 2 处有一条间距 gap,但 gap 左右还是同一条网格线 2。
网格线从左到右是数字 1, 2, 3…;从右到左是 -1, -2, -3…,即倒数第 1 条网格线,倒数第 2 条,倒数第 3 条……两者可以混用。接下来使用他们进行布局。
.container {
display: grid;
gap: 3px;
/* 三行、四等列 */
grid-template-rows: 40px 200px 40px;
grid-template-columns: repeat(4, 1fr);
}
/* 网格线 1 ~ 5 之间 */
.header {
grid-column: 1 / 5;
}
.menu {}
/* 网格线 2 ~ 倒数第 2 条网格线之间 */
.content {
grid-column: 2 / -2;
}
/* 网格线 1 ~ 倒数第 1 条网格线之间 */
.footer {
grid-column: 1 / -1;
}
即图。
grid-row
和 grid-column
的使用是类似的。
4.2 Template areas
先给自己的四个 div 色块各取个小名,header 取 h,menu 取 m,content 取 c,footer 取 f。然后给他们划分地盘。有点像排兵布阵……
这里我们要用到 grid-template-areas
和 grid-area
。
.container {
height: 100%;
display: grid;
gap: 3px;
/* 设置列宽和行高 */
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 40px auto 40px;
/* h 在第一行占 12 列, m 在第二行占第 1 列,c在第二行占第 2 列到最后一列,f 占最后一行*/
grid-template-areas:
"h h h h h h h h h h h h"
"m c c c c c c c c c c c"
"f f f f f f f f f f f f";
}
.header {
/* 所在网格位置 */
grid-area: h;
}
.menu {
grid-area: m;
}
.content {
grid-area: c;
}
.footer {
grid-area: f;
}
用 .
可以让地盘空着。
.container {
height: 100%;
display: grid;
gap: 3px;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 40px auto 40px;
grid-template-areas:
". h h h h h h h h h h ."
"m c c c c c c c c c c c"
". f f f f f f f f f f .";
}
5. 自动排列
5.1 minmax and auto-fit
minmax(最小长度, 最大长度),即长度的范围,auto-fit
能够根据所给的列宽进行自动换行。
先定义 12 个 div,接下来进行布局。
.container {
display: grid;
gap: 5px;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
grid-template-rows: repeat(2, 100px);
}
效果如下:
5.2 grid-auto-rows
上面动图里的行高不均匀。这是因为我们只设置了前两行的高度,而其余行的高度都是根据块内的内容自动定的。
我们可以使用 grid-auto-rows: 100px;
来替代 grid-template-rows: repeat(2, 100px);
,这时候,所有行高都是 100px。
5.3 auto-fit vs auto-fill
.container {
border: 1px solid black;
display: grid;
gap: 5px;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
grid-template-rows: 100px 100px;
}
.container2 {
border: 1px solid black;
display: grid;
gap: 5px;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
grid-template-rows: 100px 100px;
}
宽度过大时,auto-fit
会自动拉伸以便占满一整行,auto-fill
则不会。
待续……
文章内容是根据此处教程写的:Learn CSS Grid for free