前端入门——css Grid网格基础知识
100次浏览 发布时间:2024-11-11 10:25:23
网格布局的基本概念
CSS 网格布局引入了二维网格布局系统,可用于布局页面主要的区域布局或小型组件。不同于flex布局,flex布局是一维的,适合单行或单列的布局,而css grid(网格)是在一个二维的平面上布局元素,类似于table,不同于table的是它的子元素不受限制可以自由定位。
Grid 和 flexbox 区别
CSS网格布局和弹性盒布局的主要区别在于弹性盒布局是为一维布局服务的(沿横向或纵向的),而网格布局是为二维布局服务的(同时沿着横向和纵向)。这两个规格有一些相同的特性。如果你已经掌握如何使用弹性盒布局的话,你可能会想知道这些相似之处怎样在能帮助你掌握网格布局。
什么是网格?
网格是一组相交的水平线和垂直线,它定义了网格的列和行。我们可以将网格元素放置在与这些行和列相关的位置上。它使网页设计变得更加容易,而无需使用浮动和定位等其它技术。
CSS 网格布局具有以下特点:
- 使用固定或弹性的尺寸设置轨道的大小。
- 使用行号、行名或者标定一个网格区域来精确定位元素,同时还使用一种算法来控制未给出明确网格位置的元素。
- 对于在网格外面的内容,当必要时它会自动增加行和列,它会尽可能多地容纳所有内容。
- 可以控制网格区域中元素的对齐方式,以及整个网格如何对齐。
- 在网格单元格中可以放置多个元素,或者可以部分地彼此重叠,使用 z-index属性来控制重叠区域显示的优先级。
CSS 网格常用术语:
- 网格容器
- 网格轨道
- 网格线
- 网格单元
- 网格区域
- 网格间距
- 嵌套网格
css Grid 是一个强大的规范,当与 CSS 的其他部分(如flexbox)结合使用时,可以帮助您创建以前不可能在 CSS 中构建的布局。这一切都是通过在网格容器上创建一个网格来开始的。
网格容器
我们可以使用 display:grid 或 display:inline-grid 来创建一个网格容器。如下示例:
html:
<div class="grid-container">
<div class="grid-item">1</div>
<div class="grid-item">2</div>
<div class="grid-item">3</div>
<div class="grid-item">4</div>
<div class="grid-item">5</div>
</div>
块级网格容器:
.grid-container {
display: grid;
background-color: #2196F3;
padding: 10px;
}
.grid-item {
background-color: rgba(255, 255, 255, 0.8);
border: 1px solid rgba(0, 0, 0, 0.8);
padding: 20px;
font-size: 30px;
text-align: center;
}
显示效果:
行内块级网格容器:
.grid-container {
display: inline-grid;
background-color: #2196F3;
padding: 10px;
}
.grid-item {
background-color: rgba(255, 255, 255, 0.8);
border: 1px solid rgba(0, 0, 0, 0.8);
padding: 20px;
font-size: 30px;
text-align: center;
}
效果显示:
网格容器的所有直接子元素自动成为网格项,注意grid和inline-grid的区别。在浏览器中,元素转为网格前看不出什么差异,因为网格给这些元素创建了一个单列网格。
你可以打开开发者工具,使用选择工具选择网格容器元素,此时会在元素节点旁看到一个grid的图标,点击后会看到页面显示网格布局。如下图:
网格轨道
通过 grid-template-columns 和 grid-template-rows 属性来定义网格中的行和列,一个网格轨道就是网格中任意两条线之间的空间。
网格列轨道:
display: grid;
grid-template-columns: 200px 200px 200px;
显示效果:
网格行轨道:
display: grid;
grid-template-rows: 200px 200px 200px;
比如图5中,行一到行2之间的区域就是我们定义的行轨道。列1到列3之间的区域就是列轨道。从这里可以看出轨道不是指网格行或网格列,它们是有区别的,网格行和网格列是指网格项的水平线或垂直线,如下图:
网格轨道的大小,可以使用固定单位,如px、cm、pt等,还可以使用百分比、auto、关键字(min-content、max-content)、函数(max()、min()、minmax())等。此外还专门为网格指定一个 fr单位用来设置轨道大小,本节简单介绍下fr单位,后面会单独讲述,这方面内容太多。
fr单位
fr单位代表网格容器中可用空间的一等份。下一个网格定义将创建三个相等宽度的轨道,这些轨道会随着可用空间增长和收缩。fr 类似于 flex布局中的flex-grow。
如下示例:
display: grid;
grid-template-columns: 1fr 1fr 1fr;
如图6中,每列等宽,平分网格容器可用的空间。当将其中一列设置不同的值,如下图:
display: grid;
grid-template-columns: 1fr 2fr 1fr;
图7中,一个3列的网格,其中列2的宽度是其它列的2倍。
网格线
应该注意的是,当我们定义网格时,我们定义的是网格轨道,而不是网格线。Grid 会为我们创建带编号的网格线来让我们来定位每一个网格元素。如下示例:
列之间的线称为列线,行之间的线称为行线。可用使用grid-column-start (en-US), grid-column-end (en-US), grid-row-start (en-US) 和 grid-row-end (en-US) 属性,按照网格线编号进行定位,具体内容会在以后详细介绍。
网格线的编号顺序取决于文章的书写模式。在从左至右书写的语言中,编号为 1 的网格线位于最左边。在从右至左书写的语言中,编号为 1 的网格线位于最右边。 网格线也可以被命名,我们将在稍后的教程中看到如何完成这一操作。
网格单元
一个网格单元是在一个网格元素中最小的单位, 从概念上来讲其实它和表格里的一个单元格很像。现在再看回我们前面的一个例子,一旦一个网格元素被定义在一个父级元素当中,那么他的子级元素将会排列在每个事先定义好的网格单元中。在下面的图中,我会将第一个网格单元作高亮处理。
网格区域
网格元素可以向行或列的方向扩展一个或多个单元,并且会创建一个网格区域。网格区域的形状应该是一个矩形 - 也就是说你不可能创建出一个类似于“L”形的网格区域。下图高亮的网格区域扩展了 2 列以及 2 行。
网格间距
每列/行之间的空间称为网格间距。可使用 grid-column-gap (en-US) 和 grid-row-gap (en-US) 属性来创建,或者直接使用两个合并的缩写形式 grid-gap (en-US)。在下面的例子中,我会创建一个横向间距为 10px、纵向间距为 1em 的网格元素。
css:
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-column-gap: 10px;
grid-row-gap: 1em;
}
html:
<div class="wrapper">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
效果显示:
间距使用的空间会在使用弹性长度 fr 的轨道的空间计算前就被留出来,间距的尺寸定义行为和普通轨道一致,但不同的是你不能向其中插入任何内容。从以基线定位的角度来说,间距就像一条很宽的基线。
嵌套网格
一个网格元素可以也成为一个网格容器。在接下来的例子中我事先有了一个 3 列的网格元素,并有两个跨轨道的网格。在这个例子中,第一个网格元素含有几个子级元素。当这些元素不是网格容器的直接子级元素时,它们不会参与到网格布局中,并显示为正常的文档流。
如下示例:
html:
<div class="wrapper">
<div class="box box1">
<div class="nested">a</div>
<div class="nested">b</div>
<div class="nested">c</div>
</div>
<div class="box box2">Two</div>
<div class="box box3">Three</div>
<div class="box box4">Four</div>
<div class="box box5">Five</div>
</div>
css:
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-column-gap: 10px;
grid-row-gap: 1em;
background:#000;
}
.wrapper > div {
background-color: rgba(255, 255, 255, 0.8);
border: 1px solid rgba(0, 0, 0, 0.8);
padding: 20px;
font-size: 30px;
text-align: center;
}
.nested{
background-color: rgba(255, 255, 255, 0.8);
border: 1px solid rgba(0, 0, 0, 0.8);
}
当我们给box1设置display: grid;如下图显示:
box1 {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-column-gap: 10px;
grid-row-gap: 1em;
}
图13中box1它也会变成一个网格元素,它的子级元素也会排列在这个新网格元素中。
在这个例子中,嵌套网格和他的父级并没有关系。就像你在例子中所看见的一样,它并没有从它的父级继承 grid-gap (en-US) 属性,并且嵌套网格里面的网格线没有与父级的网格线对齐。
网格单元重叠
多个网格项目可以占用同一个网格单位。如下图示例:
html:
<div class="wrapper">
<div class="box box1">One</div>
<div class="box box2">Two</div>
<div class="box box3">Three</div>
<div class="box box4">Four</div>
<div class="box box5">Five</div>
</div>
css:
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px;
column-gap: 10px;
row-gap: 10px;
}
.box{
background: #fff;
border:1px solid #000;
}
.box1 {
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
background:red;
}
.box2 {
grid-column-start: 1;
grid-row-start: 2;
grid-row-end: 4;
background:orange;
}
效果显示:
网格 box2 现在覆盖于 box1 之上,其覆盖顺序遵循文档流的原始顺序(后来居上)。
我们可以使用 z-index 属性控制重叠的顺序。如果我们给 box2 设定一个低于 box1 的 z-index 值的话,box2将会显示在 box1 的下方。如下示例:
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px;
column-gap: 10px;
row-gap: 10px;
}
.box{
background: #fff;
border:1px solid #000;
}
.box1 {
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
background:red;
z-index:2;
}
.box2 {
grid-column-start: 1;
grid-row-start: 2;
grid-row-end: 4;
background:orange;
z-index:1;
}
显示效果: