当前位置: 首页 > article >正文

CSS 系列之:grid 布局

基本概念

<template>
  <div class="parent">
    <div class="box">p1-1</div>
    <div class="box">p1-2</div>
    <div class="box">p1-3</div>
  </div>

  <div class="parent">
    <div class="box">p2-1</div>
    <div class="box">p2-2</div>
    <div class="box">p2-3</div>
  </div>
</template>

<style scoped>
.parent {
  background-color: skyblue;
  display: grid; // 块级容器,宽度撑满整行
  /* display: inline-grid; */ // 行内容器,宽度随内容自适应
}

.box {
  border: 1px solid #000;
}
</style>

最外层的 <div class="parent"> 称为容器,内层的三个 <div class="children"> 称为项目(或网格项)。

使用网格布局后,项目的 float、display: inline-block、display: table-cell、vertical-align、column-* 等设置都将失效。

在这里插入图片描述
在这里插入图片描述

指定行列

grid-template-columns 指定划分列数

grid-template-rows 指定划分行数

固定宽高 px

<template>
  <div class="parent">
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="box">4</div>
    <div class="box box5">5</div>
  </div>
</template>

<style scoped>
.parent {
  background-color: skyblue;
  display: grid;
  /* 3 列 */
  grid-template-columns: 100px 100px 100px;
  /* 2 行 */
  grid-template-rows: 50px 40px;
}

.box {
  border: 1px solid #000;
  margin: 10px;
}
</style>

在这里插入图片描述
可以看到 grid-template-columns 和 grid-template-rows 设置的值是包含 margin 在内的。

使用了 grid-template-columns 和 grid-template-rows 后还可以单独给项目设置宽高吗?答案是可以的。

.box5 {
  height: 80px;
}

在这里插入图片描述
单独设置宽高是不包含 margin 的,且容器的宽高不会受它影响。

百分比 %

  • 如果 .parent 没有显式设置 width 和 height ,则 100% 将等于 .parent 自然展开后的宽高。

  • 如果 .parent 有显式的 width 和 height 值,那么 100% 就等于该指定的宽高值。

<template>
  <div class="parent">
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="box">4</div>
    <div class="box">5</div>
    <div class="box">6</div>
    <div class="box">
      <div style="height: 30px;">7</div>
    </div>
  </div>

</template>

<style scoped>
.parent {
  background-color: skyblue;
  display: grid;
  /* 3 列 */
  grid-template-columns: 40% 30% 20%;
  /* 2 行 */
  grid-template-rows: 100% 50%;
}

.box {
  border: 1px solid #000;
  margin: 10px;
}
</style>

在这里插入图片描述
第 7 个 项目的高度没有被 grid-template-rows 设置到,则第 7 个 div 的高度是他实际内容的高度。

重复设置 repeat

使用 repeat 统一设置值,第一个参数为重复数量,第二个参数是重复值

<template>
  <div class="parent">
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="box">4</div>
    <div class="box">5</div>
    <div class="box">6</div>
    <div class="box">7</div>
  </div>

</template>

<style scoped>
.parent {
  background-color: skyblue;
  display: grid;
  /* 3 列 */
  grid-template-columns: repeat(3, 40%);
  /* 2 行 */
  grid-template-rows: repeat(2, 50%);
}

.box {
  border: 1px solid #000;
  margin: 10px;
}
</style>

在这里插入图片描述
项目总宽度超过 100% 时会产生滚动条。

repeat 还可以设置多个值:

<template>
  <div class="parent">
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="box">4</div>
    <div class="box">5</div>
    <div class="box">6</div>
    <div class="box">7</div>
  </div>

</template>

<style scoped>
.parent {
  background-color: skyblue;
  display: grid;
  grid-template-columns: repeat(2, 200px 100px);
  grid-template-rows: repeat(2, 50px);
}

.box {
  border: 1px solid #000;
  margin: 10px;
}
</style>

在这里插入图片描述

自动填充 auto

用于填充满所有剩余空间

<template>
  <div class="parent">
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="box">4</div>
    <div class="box">5</div>
    <div class="box">6</div>
    <div class="box">7</div>
  </div>

</template>

<style scoped>
.parent {
  background-color: skyblue;
  display: grid;
  grid-template-columns: 100px 20% auto;
}

.box {
  border: 1px solid #000;
  margin: 10px;
}
</style>

在这里插入图片描述

比例划分 fr

fr 是 fraction 的缩写,意为"片段"。

<template>
  <div class="parent">
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="box">4</div>
    <div class="box">5</div>
    <div class="box">6</div>
    <div class="box">7</div>
  </div>

</template>

<style scoped>
.parent {
  background-color: skyblue;
  display: grid;
  grid-template-columns: 100px 1fr 2fr;
  grid-template-rows: 3fr 1fr 2fr;
}

.box {
  border: 1px solid #000;
  margin: 10px;
}
</style>

在这里插入图片描述

假设容器总宽度是 800px,grid-template-columns: 100px 1fr 2fr 则表示第一列占据 100px 宽度,第二列占据剩余 700px 的三分之一的宽度,第三列占据剩余 700px 的三分之二的宽度。

所以 grid-template-columns: 100px 20% 1fr 中最后一列的 1fr 其实也是铺满剩余空间的意思。

repeat 中也能用 fr。

最大最小值 minmax

minmax() 函数产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值。

<template>
  <div class="parent">
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="box">4</div>
    <div class="box">5</div>
    <div class="box">6</div>
    <div class="box">7</div>
  </div>

</template>

<style scoped>
.parent {
  background-color: skyblue;
  display: grid;
  grid-template-columns: 100px 100px minmax(100px, 1fr);
  grid-template-rows: 3fr 1fr 2fr;
}

.box {
  border: 1px solid #000;
  margin: 10px;
}
</style>

最后一列表示宽度最小 100px,最大铺满剩余空间。
在这里插入图片描述

自动调整 auto-fit 和 auto-fill

<template>
  <div class="parent auto-fit">
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
  </div>
  <div class="parent auto-fill">
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
  </div>
</template>

<style scoped>
.parent {
  background-color: skyblue;
  display: grid;
  width: 600px;
  margin-bottom: 20px;
}

.auto-fit {
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
}

.auto-fill {
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
}

.box {
  border: 1px solid #000;
  margin: 10px;
}
</style>

在这里插入图片描述

容器宽度为 600px,我们希望在其中放置一些最小宽度为 100px 的项目,每个项目的最大宽度为 1fr(即剩余空间的等分部分)。

理论上可以创建 6 个 100px 宽的列,但只有 3 个项目,所以会有 3 个空的列。

auto-fit 会合并多余的空列,使现有列扩展以填满所有可用空间。

auto-fill 仍然会创建 6 个列,但其中 3 个列将是空的。

在这里插入图片描述
在这里插入图片描述
auto-fill 和 auto-fit 关键需要与 repeat() 函数和 minmax() 函数一起使用,才能发挥它们的作用。

在上例中我们看到,使用 auto-fill 时,项目的宽度始终时 minmax(100px, 1fr) 中的最小值 100px,那么 1fr 的作用是什么呢?

直接说结论:

  • 当容器的宽度小于等于项目的宽度时,1fr 不会起作用

  • 当容器的宽度是项目的宽度的整数倍时,1fr 不会起作用

  • 当容器的宽度是项目的宽度的大于 1 的小数倍时,1fr 才会起作用

例如把上面的例子中改成:

.parent {
	width: 460px
}

在这里插入图片描述
每个项目宽度是 115px,被扩充了。

总结:

auto-fit 和 auto-fill 都会尝试创建尽可能多的项目,例如 460px 的容器最多可以创建 4 个最小宽度为 100px 的项目,但是 html 中只有 3 个项目,对多出的这 1 个空白项目和剩余的额外 60px 空间的处理方式就是 auto-fit 和 auto-fill 的区别

  • auto-fit 会吞并多出的空白项目,使现有项目扩展以填满所有剩余空间

  • auto-fill 会保留多出的空白项目,空白项目会占据空间,如果有剩余的额外,则所有项目会扩展以填满剩余额外空间

指定区域

grid-template-areas

可以将网格布局中的某个单元格或多个单元格定义为一个区域。

网格区域一定要形成规整的矩形区域,无论是 L 形,还是凹的或凸的形状都会认为是无效的属性值。

按固定数值划分

<template>
  <div class="parent">
    <div class="box top">top</div>
    <div class="box left">left</div>
    <div class="box right">right</div>
    <div class="box bottom">bottom</div>
  </div>
</template>

<style scoped>
.parent {
  background-color: skyblue;
  height: 100%;
  display: grid;
  grid-template-columns: 50px auto;
  grid-template-rows: 70px auto 70px;
  grid-template-areas:
    "top top"
    "left right"
    "bottom bottom";
}

.box {
  border: 1px solid #000;
}

.top {
  grid-area: top;
}

.left {
  grid-area: left;
}

.right {
  grid-area: right;
}

.bottom {
  grid-area: bottom;
}
</style>

在这里插入图片描述

按比例划分

<template>
  <div class="parent">
    <div class="box top">top</div>
    <div class="box left">left</div>
    <div class="box right">right</div>
    <div class="box bottom">bottom</div>
  </div>
</template>

<style scoped>
.parent {
  background-color: skyblue;
  height: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr 1fr;
  grid-template-areas:
    "top top top"
    "left right right"
    "left right right"
    "bottom bottom bottom";
}

.box {
  border: 1px solid #000;
}

.top {
  grid-area: top;
}

.left {
  grid-area: left;
}

.right {
  grid-area: right;
}

.bottom {
  grid-area: bottom;
}
</style>

在这里插入图片描述

grid-tempalte

是 grid-template-rows、grid-template-columns、grid-template-areas 的三个属性的简写。

按固定数值划分

上面的按固定数值划分可以改造为:

.parent {
  background-color: skyblue;
  height: 100%;
  display: grid;
  grid-template:
    "top top" 70px
    "left right" auto
    "bottom bottom" 70px
    / 50px auto;
}

第一行 "top top" 70px 定义了一个名为 top 的区域占据前两列,并且该区域所在行的高度为 70px。

第二行 "left right" auto 定义了一个名为 left 的区域占据第一列和一个名为 right 的区域占据第二列,并且该区域所在行的高度为 auto。

第三行 "bottom bottom" 70px 定义了一个名为 bottom 的区域占据前两列,并且该区域所在行的高度为 70px。

最后的 / 50px auto 定义了列的大小:第一列的宽度为 50px,第二列的宽度为 auto。

按比例划分

上面的按比例划分可以改造为:

.parent {
  background-color: skyblue;
  height: 100%;
  display: grid;
  grid-template:
    "top top top" 1fr
    "left right right" 1fr
    "left right right" 1fr
    "bottom bottom bottom" 1fr
    / 1fr 1fr 1fr;
}

一行可以有多个不同的高度吗?例如把第一行改成 "top top top" 1fr 50px。答案是不行,会导致错乱。

点代表占位符

.parent {
  background-color: skyblue;
  height: 100%;
  display: grid;
  grid-template:
    "top top ." 1fr
    "left . ." 1fr
    "right . ." 1fr
    "bottom bottom bottom" 1fr
    / 1fr 1fr 1fr;
}

在这里插入图片描述
注意:

一个元素不能同时占据多个不连续的网格区域。

也就是说 "top top ."". top . "". . top" 等等都是允许的,但是 "top . top" 是不允许的。

其实 top 对应的是一个 html 元素,它要么占据连续的区域,要么占据一个单独的单元格,它不能分裂成不连续的部分。

定义间距

行间距 row-gap

列间距 column-gap

<template>
  <div class="parent">
    <div class="box">1</div>
    <div class="box">2</div>
    <div class="box">3</div>
    <div class="box">4</div>
    <div class="box">5</div>
    <div class="box">6</div>
    <div class="box">7</div>
  </div>
</template>

<style scoped>
.parent {
  background-color: skyblue;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  column-gap: 30px;
  row-gap: 20px;
}

.box {
  border: 1px solid #000;
}
</style>

在这里插入图片描述

组合定义 gap

组合写法 gap: 20px 30px; 先行(row)后列(column)

元素定位

grid-row/column-start/end

样式属性说明
grid-row-start行开始网格线
grid-row-end行结束网格线
grid-column-start列开始网格线
grid-column-end列结束网格线
属性值说明
Line网格络
span 数值网格包含的网格数量
span 区域名称网格包含到指定的区域名称
auto自动设置,默认为一个网格宽度和高度

用于指定一个网格项目的开始行(列)和结束行(列)的位置。

例如:

.grid-item1 {
    grid-row-start: 1; /* 从第 1 行开始 */
    grid-row-end: 3;   /* 到第 3 行结束(不包括第 3 行,即跨越两行) */
}

.grid-item2 {
    grid-row-start: 1;
    grid-row-end: span 2; /* 从第 1 行开始,跨越 2 行 */
}

行线 1 对应第一行的上边缘
行线 2 对应第二行的上边缘
行线 3 对应第三行的上边缘

grid-row-start 通常要比 grid-row-end 小,否则会导致一些意想不到的结果。

<template>
  <div class="parent">
    <div class="box box1">1</div>
    <div class="box box2">2</div>
    <div class="box box3">3</div>
    <div class="box box4">4</div>
    <div class="box box5">5</div>
    <div class="box box6">6</div>
    <div class="box box7">7</div>
  </div>
</template>

<style scoped>
.parent {
  background-color: skyblue;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: 20px 30px;
}

.box {
  border: 1px solid #000;
}

.box1 {
  grid-row-start: 1;
}
</style>

在这里插入图片描述


.box1 {
  grid-row-start: 2;
}

在这里插入图片描述


.box1 {
  grid-row-start: 3;
}

在这里插入图片描述


.box1 {
  grid-row-start: 4;
}

在这里插入图片描述


.box1 {
  grid-row-start: 1;
  grid-row-end: 3; /* 当该值是 1 和 2 时表现形式和默认图相同,直接从 3 开始 */
}

在这里插入图片描述


.box1 {
  grid-row-start: 1;
  grid-row-end: 4;
}

在这里插入图片描述


.box1 {
  grid-row-start: 1;
  grid-row-end: 5;
}

在这里插入图片描述


.box1 {
  grid-row-start: 1;
  grid-row-end: 6;
}

在这里插入图片描述

简写模式 grid-row、grid-column

grid-row 和 grid-column

语法:

grid-row: grid-row-start / grid-row-end;
grid-column: grid-row-column / grid-row-column;

例如:

.box1 {
  grid-row-start: 1;
  grid-row-end: 6;
}

就可以简写成

.box1 {
  grid-row: 1/6;
}

超级简写模式 grid-area

grid-area: grid-row-start / grid-column-start / grid-row-end / grid-column-end;

网格流动 grid-auto-flow

在容器中设置 grid-auto-flow 属性可以改变单元格排列方式。

选项说明
row按行排列,默认值
column按列排序
row dense网格将尝试在行方向上尽可能紧密地放置项目,尽量不出现空格
column dense网格将尝试在列方向上紧密放置项目,尽量不出现空格
<template>
  <div class="parent">
    <div class="box box1">1</div>
    <div class="box box2">2</div>
    <div class="box box3">3</div>
    <div class="box box4">4</div>
    <div class="box box5">5</div>
    <div class="box box6">6</div>
    <div class="box box7">7</div>
  </div>
</template>

<style scoped>
.parent {
  background-color: skyblue;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: 20px 30px;
  grid-auto-flow: row;
}

.box {
  border: 1px solid #000;
}
</style>

在这里插入图片描述

grid-auto-flow: column

在这里插入图片描述

设置单元格对齐方式

justify-items

指定单元格内容的水平对齐方式

属性描述
stretch默认值,占满单元格的整个宽度
start对齐单元格的起始边缘
end对齐单元格的结束边缘
center单元格内部居中
<template>
  <div class="parent">
    <div class="box box1">1</div>
    <div class="box box2">2</div>
    <div class="box box3">3</div>
    <div class="box box4">4</div>
    <div class="box box5">5</div>
    <div class="box box6">6</div>
    <div class="box box7">7</div>
  </div>
</template>

<style scoped>
.parent {
  background-color: skyblue;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: repeat(3, 50px);
  gap: 20px;
}

.box {
  border: 1px solid #000;
}
</style>

在这里插入图片描述


.parent {
	justify-items: start
}

在这里插入图片描述


.parent {
	justify-items: center
}

在这里插入图片描述


.parent {
	justify-items: end
}

在这里插入图片描述

align-items

指定单元格内容的垂直对齐方式

normal默认值,会根据使用场景的不同表现为 stretch 或者 start
stretch拉伸,占满单元格的整个宽度
start对齐单元格的起始边缘
end对齐单元格的结束边缘
center单元格内部居中
baseline基线对齐
.parent {
	align-items: normal; // 或 stretch
}

在这里插入图片描述


.parent {
	align-items: start;
}

在这里插入图片描述


.parent {
	align-items: center;
}

在这里插入图片描述


.parent {
	align-items: end;
}

在这里插入图片描述

place-items

是 align-items 属性和 justify-items 属性的合并简写形式。

.parent {
	// 先垂直方向,再水平方向
	place-items: start end;
}

在这里插入图片描述


IE 浏览器和 Edge 浏览器都不支持 place-items 属性。如果不考虑浏览器的兼容性,在 CSS 中实现垂直居中对齐效果的最佳方法就是使用 grid 布局的 place-items 属性:

.parent {
	// 如果省略第二个值,则浏览器认为与第一个值相等
	place-items: center;
}

在这里插入图片描述

justify-self

跟 justify-items 属性的用法完全一致,但只作用于单个项目。

.box1 {
  justify-self: center
}

在这里插入图片描述

align-self

跟 align-items 属性的用法完全一致,也是只作用于单个项目。

.box1 {
  align-self: center
}

在这里插入图片描述

place-self

是 align-self 属性和 justify-self 属性的合并简写形式,跟 place-items 属性的用法完全一致。

.box1 {
  place-self: center
}

在这里插入图片描述

设置容器内的对齐方式

justify-content

项目在水平方向对齐方式

align-content

项目在垂直方向对齐方式

与 flex 布局中的类似。

注意:要想 justify-content 属性和 align-content 属性起作用,就需要让项目的总尺寸小于 grid 容器的尺寸。

<template>
  <div class="parent">
    <div class="box box1">1</div>
    <div class="box box2">2</div>
    <div class="box box3">3</div>
    <div class="box box4">4</div>
    <div class="box box5">5</div>
    <div class="box box6">6</div>
    <div class="box box7">7</div>
  </div>
</template>

<style scoped>
.parent {
  background-color: skyblue;
  display: grid;
  grid-template-columns: repeat(3, 50px);
  grid-template-rows: repeat(3, 50px);
  gap: 20px;
  width: 100%;
  height: 300px;
}

.box {
  border: 1px solid #000;
}
</style>

在这里插入图片描述


.parent {
	justify-content: space-between;
}

在这里插入图片描述

place-content

是 align-content 属性和 justify-content 属性的合并简写形式。如果省略第二个值,浏览器就会假定第二个值等于第一个值。

.parent {
	// 先垂直方向,再水平方向
	place-content: center space-between;
}

在这里插入图片描述

xxx-item 和 xxx-content 的区别

xxx-item 用于控制容器内每个项目的对齐方式。它影响的是每个单独的项目在其所在单元格内的对齐方式。

xxx-content 用于控制容器内的所有项目的对齐方式。它影响的是所有项作为一个整体如何在容器内分配空间。

参考链接:

CSS3最强布局-Grid布局

css【详解】grid布局—— 网格布局(栅格布局)


http://www.kler.cn/a/566767.html

相关文章:

  • Windows环境下安装Redis并设置Redis开机自启
  • React进阶之前端业务Hooks库(三)
  • docker部署go简单web项目(无mysql等附加功能)
  • React组件化深度解析(二):从受控组件到生命周期现代化
  • 【Wireshark 02】抓包过滤方法
  • 三十、Helm和Operator
  • PDF文档中表格以及形状解析
  • 密码学(哈希函数)
  • 3-4 WPS JS宏 工作表的新建、删除与错务内容处理(批量新建工作表)学习笔记
  • 【考试大纲】高级系统架构设计师考试大纲
  • uniapp中使用leaferui使用Canvas绘制复杂异形表格的实现方法
  • Angular从入门到精通教程篇章
  • 多个pdf合并成一个pdf的方法
  • MySQL当中的Lock
  • Gatling介绍
  • k8s出问题后 应该查看哪些内容
  • 【Leetcode 每日一题】2353. 设计食物评分系统
  • Netty为什么性能很高?
  • Android Logcat 高效调试指南
  • SVT-AV1接入ffmpeg说明