CSS Grid 布局
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
则不会。
待续……