前言
如果说 Flex 布局是一维的“线性布局”,那么 Grid(网格布局) 就是真正意义上的“二维布局”。它能够同时处理行与列,让我们通过简单的代码就能实现极其复杂的页面结构。
一、 Grid 容器属性:定义你的网格空间
1. 开启网格布局
display: grid;:容器里面的元素为块级元素。display: inline-grid;:容器里面的元素为行内元素。
2. 定义行与列 (grid-template-*)
通过 grid-template-columns 和 grid-template-rows 划分网格。
-
常用关键字:
repeat(count, value):重复定义。例如repeat(3, 1fr)表示三列均分。auto-fill:自动填充。让每一行/列尽可能容纳更多固定宽度的单元格。fr(Fraction) :片段单位。表示网格剩余空间的比例关系。minmax(min, max):长度范围。例如minmax(100px, 1fr)。auto:自适应,占满剩余宽度。
注意:不要单独使用grid-template-rows,单独使用grid布局可能会造成布局混乱,不可预测。
- 使用实例:当网格单元格数量大于子元素数量时,多余单元格会保持空白,子元素不会因此被拉伸放大。 例如:定义一个 3列×4行 的网格,但只放入9个元素,剩余3个单元格会留空,而现有元素仍保持正常的网格比例尺寸
<!DOCTYPE html>
<html>
<body>
<div class="container">
<div class="grid-container">
<div class="div">1</div>
<div class="div">2</div>
<div class="div">3</div>
<div class="div">4</div>
<div class="div">5</div>
<div class="div">6</div>
<div class="div">7</div>
<div class="div">8</div>
</div>
</div>
<script></script>
</body>
<style>
html,
body {
height: 100vh;
margin: 0;
padding: 0;
}
.container {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.grid-container {
width: 500px;
height: 800px;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(4, 1fr);
}
.div {
border: 1px solid salmon;
}
</style>
</html>
3. 间距 (Gap)
注意:最新标准中已建议移除
grid-前缀,直接使用gap。
row-gap:行间距。column-gap:列间距。gap:合写形式(<row-gap> <column-gap>)。
.grid-container {
width: 500px;
height: 800px;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(4, 1fr);
column-gap: 20px;
row-gap: 20px;
}
二、 网格排列与对齐控制
1. 单元格内容对齐 (-items)
控制网格项在网格表内部的位置:
justify-items:网格中每行的水平对齐方式(start | end | center | stretch)。align-items:格中每行的垂直对齐方式。place-items:简写形式。
注意:当 Grid 子元素的宽高都超过了父容器时,
justify-items和align-items可能会失效或不明显,所以尽量网格容器与子元素宽高可预知场景下使用。
实例:例如现在我给每个单元格都设置一个小于网格的宽高,这时就可直观看到它们的区别了
<!DOCTYPE html>
<html>
<body>
<div class="container">
<div class="grid-container">
<div class="div">1</div>
<div class="div">2</div>
<div class="div">3</div>
<div class="div">4</div>
<div class="div">5</div>
<div class="div">6</div>
<div class="div">7</div>
<div class="div">8</div>
</div>
</div>
<script></script>
</body>
<style>
html,
body {
height: 100vh;
margin: 0;
padding: 0;
}
.container {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.grid-container {
width: 500px;
height: 800px;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(4, 1fr);
column-gap: 20px;
row-gap: 20px;
align-items: center; /* 网格中每行的水平对齐方式 */
justify-items: center;/* 网格中每行的垂直对齐方式 */
border: 1px solid yellow;
}
.div:nth-child(2n) {
width: 30px;
height:30px;
border: 1px solid salmon;
}
.div:nth-child(2n + 1) {
width: 50px;
height: 50px;
border: 1px solid green;
}
</style>
</html>
2. 整个网格内容区域对齐 (-content)
在实际使用中,存在着网格内容区域大小和网格容器大小不一致的情况,而-content则是设置网格内容区域相对于容器的对齐方式。
justify-content:网格内容区域在水平位置相当于容器的对齐方式(space-between | space-around | space-evenly | strat | end | center |stretch(大小没有指定时,拉伸占据整个网格容器))。align-content:网格内容区域在垂直方向相对于容器的对齐方式。place-content:简写形式。
在上面的例子中,可以发现添加justify-content与align-content是无效的,因为网格内容区域总尺寸 = 容器尺寸,现在将网格中子项设置较大值与较小值,你就会发现区别:图左为网格内容区域总尺寸 > 容器尺寸,图右边为网格内容区域总尺寸 < 容器尺寸。
.container {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.grid-container {
width: 500px;
height: 800px;
display: grid;
grid-template-columns: repeat(3, 200px); /* repeat(3, 100px) */
grid-template-rows: repeat(4, 350px); /*repeat(4, 150px); */
column-gap: 20px;
row-gap: 20px;
align-items: center; /* 网格中每行的水平对齐方式 */
justify-items: center;/* 网格中每行的垂直对齐方式 */
justify-content: center; /*网格内容区域在水平位置相当于容器的对齐方式*/
align-content: center; /*网格内容区域在垂直方向相当于容器的对齐方式*/
border: 1px solid yellow;
}
3. 排列顺序 (grid-auto-flow)
决定网格项如何自动填充到网格中。
row(默认):先行后列。column:先列后行。
三、 项目属性:单个格子的自我修养
1. 基于网格线的定位
可以通过指定网格线来决定一个项目跨越多少行或列。
grid-column-start / end:元素左边框所在的垂直网格线/右边框所在的垂直网格线。grid-row-start / end:元素上边框所在的水平网格线/下边框所在的水平网格线。span关键字:表示跨越的跨度。例如grid-column: span 2;(跨越两列)。
<!DOCTYPE html>
<html>
<body>
<div class="container">
<div class="grid-container">
<div class="div">1</div>
<div class="div">2</div>
<div class="div">3</div>
<div class="div">4</div>
<div class="div">5</div>
<div class="div">6</div>
<div class="div">7</div>
<div class="div">8</div>
</div>
</div>
<script></script>
</body>
<style>
html,
body {
height: 100vh;
margin: 0;
padding: 0;
}
.container {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.grid-container {
width: 500px;
height: 800px;
display: grid;
grid-template-columns: repeat(3, 1fr); /* repeat(3, 100px) */
grid-template-rows: repeat(4, 1fr); /*repeat(4, 150px); */
column-gap: 20px;
row-gap: 20px;
/* grid-auto-flow: column; */
align-items: center; /* 网格中每行的水平对齐方式 */
justify-items: center; /* 网格中每行的垂直对齐方式 */
justify-content: center; /*网格内容区域在水平位置相当于容器的对齐方式*/
align-content: center; /*网格内容区域在垂直方向相当于容器的对齐方式*/
border: 1px solid yellow;
}
.div:nth-child(2n) {
width: 100%;
height: 100%;
border: 1px solid salmon;
}
.div:nth-child(2n + 1) {
width: 100%;
height: 100%;
border: 1px solid green;
}
.div:last-child{
background: red;
grid-column-start:2;
grid-column-end: 4;
grid-row-start: 3;
grid-row-end: 5;
}
</style>
</html>
2. 单个项目的对齐 (-self)
适用于网格内的的子元素,它会覆盖容器定义的 items 属性:
justify-self:置单元格内容的水平位置(左中右),跟justify-items属性的用法完全一致,但只作用于单个项目。取值:start | end | center | stretch(拉伸)align-self:设置单元格内容的垂直位置(上中下)place-self:是align-self属性和justify-self属性的合并简写形式
<!DOCTYPE html>
<html>
<body>
<div class="container">
<div class="grid-container">
<div class="div">1</div>
<div class="div">2</div>
<div class="div">3</div>
<div class="div">4</div>
<div class="div">5</div>
<div class="div">6</div>
<div class="div">7</div>
<div class="div">8</div>
</div>
</div>
<script></script>
</body>
<style>
html,
body {
height: 100vh;
margin: 0;
padding: 0;
}
.container {
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.grid-container {
width: 500px;
height: 800px;
display: grid;
grid-template-columns: repeat(3, 1fr); /* repeat(3, 100px) */
grid-template-rows: repeat(4, 1fr); /*repeat(4, 150px); */
column-gap: 20px;
row-gap: 20px;
/* grid-auto-flow: column; */
align-items: center; /* 网格中每行的水平对齐方式 */
justify-items: center; /* 网格中每行的垂直对齐方式 */
justify-self: start;
justify-content: center; /*网格内容区域在水平位置相当于容器的对齐方式*/
align-content: center; /*网格内容区域在垂直方向相当于容器的对齐方式*/
border: 1px solid yellow;
}
.div{
justify-self: end;
align-self: end;
}
.div:nth-child(2n) {
width: 30px;
height: 30px;
border: 1px solid salmon;
}
.div:nth-child(2n + 1) {
width: 50px;
height: 50px;
border: 1px solid green;
}
.div:last-child{
width: 100%;
height: 100%;
background: red;
grid-column-start:2;
grid-column-end: 4;
grid-row-start: 3;
grid-row-end: 5;
}
</style>
</html>