CSS Grid Layout是CSS为布局新增的一个模块。网格布局特性主要是针对于Web应用程序的开发者。可以用这个模块实现许多不同的布局。网络布局可以将应用程序分割成不同的空间,或者定义他们的大小、位置以及层级。
就像表格一样,网格布局可以让Web设计师根据元素按列或行对齐排列,但它和表格不同,网格布局没有内容结构,从而使各种布局不可能与表格一样。例如,一个网格布局中的子元素都可以定位自己的位置,这样他们可以重叠和类似元素定位。
此外,没有内容结构的网格布局有助于使用流体、调整顺序等技术管理或更改布局。通过结合CSS的媒体查询属性,可以控制网格布局容器和他们的子元素,使用页面的布局根据不同的设备和可用空间调整元素的显示风格与定位,而不需要去改变文档结构的本质内容。
基本概念
在学习网格布局之前,首先需要了解在网格布局中经常会用到一些基本概念:
- 网格线(Grid Lines):网格线组成了网格,他是网格的水平和垂直的分界线。一个网格线存在行或列的两侧。我们可以引用它的数目或者定义的网格线名称。
- 网格轨道(Grid Track):网格轨道是就是相邻两条网格线之间的空间,就好比表格中行或列。所在在网格中其分为grid column和grid row。每个网格轨道可以设置一个大小,用来控制宽度或高度。
- 网格单元(Grid Cell):网格单元格是指四条网格线之间的空间。所以它是最小的单位,就像表格中的单元格。
- 网格区域(Grid Area):网格区域是由任意四条网格线组成的空间,所以他可能包含一个或多个单元格。相当于表格中的合并单元格之后的区域。
- 网格容器(Grid Containers):通过使用display属性给元素显式设置了属性值grid或inline-grid,此时这个元素将自动变成网格容器。这个类似于flexbox一样,将元素设置设置display:flex元素将自动变成弹性盒模型。由于网格容器不是块容器,所以有部分属性在网格布局中将会失效:多列布局模块中的所有column-*属性运用在网格容器上将失效float和clear使用在网格项目(网格单元格Grid Cell)上将失效vertical-align使用在网格单元格上将失效::first-line和::first-letter这样的伪元素不能应用在网格容器上
- 网格单元格顺序(order)网格单元格顺序和Flexbox模块一样,通过order属性来对网格单父元格进行顺序重排。
- 列线起始线(grid-column-start)
- 列线终止线(grid-column-end)
- 行线起始线(grid-row-start)
- 行线终止线(grid-row-end)
简单网格布局
基于grid-template创建网格
创建网格最基本的方法是通过grid-template-columns和grid-template-rows属性创建网格。
.demo{
display: grid;
grid-template-columns:100px 50px 100px 50px 100px;
grid-template-rows:100px 50px 100px;
}
.box{
background-color:#444;
color:#fff;
font-size: 150%;
padding:20px;
border:1px solid blue;
}
.b,.d,.g,.i{
background-color:red;
}
<div class="demo">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
<div class="box g">G</div>
<div class="box h">H</div>
<div class="box i">I</div>
<div class="box j">J</div>
</div>
在上面的代码中,首先给父元素添加属性display:grid来定义一个网格,再通过grid-template-columns和grid-template-rows创建了一个3行5列的网格,grid-template-columns依次定义了每一列的宽度,grid-template-rows依次定义了每一行的高度,然后浏览器将容器中的子元素走动填到每一个网格单元中,当超过指定的列数时,网格会自动换行,于是得到了上图所示的效果,每一行有5个网格单元,宽度依次为100px 50px 100px 50px 100px,只有当网格单元超过指定列数时,才会换行到第二行,其中第一行的高度为100px,第二行的高度为50px。
基于网格线的网格
在上面的实例中,我们通过一个属性定义实现了最简单的网格,此时每个网格都是按照顺序自动排列的,在实际生活中,我们常常是采用网格线来定义网格单元的,每一网格单元的位置由相应的行列起止线决定。
.demo {
display: grid;
grid-template-columns: 100px 10px 100px 10px 100px 10px 100px;
grid-template-rows: 70px 10px 70px 10px 70px;
}
.box {
background-color: #444;
color: #fff;
font-size: 150%;
padding: 20px;
text-align: center;
}
.a {grid-column-start: 1;grid-column-end: 2; grid-row-start: 1;grid-row-end: 2;}
.b {grid-column-start: 3;grid-column-end: 4; grid-row-start: 1;grid-row-end: 2;}
.c {grid-column-start: 5;grid-column-end: 6; grid-row-start: 1;grid-row-end: 2;}
.d {grid-column-start: 7;grid-column-end: 8; grid-row-start: 1;grid-row-end: 2;}
.e {grid-column-start: 1;grid-column-end: 2; grid-row-start: 3;grid-row-end: 4;}
.f {grid-column-start: 3;grid-column-end: 4; grid-row-start: 3;grid-row-end: 4;}
.g {grid-column-start: 5;grid-column-end: 6; grid-row-start: 3;grid-row-end: 4;}
.h {grid-column-start: 7;grid-column-end: 8; grid-row-start: 3;grid-row-end: 4;}
.i {grid-column-start: 1;grid-column-end: 2; grid-row-start: 5;grid-row-end: 6;}
.j {grid-column-start: 3;grid-column-end: 4; grid-row-start: 5;grid-row-end: 6;}
<div class="demo">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
<div class="box e">E</div>
<div class="box f">F</div>
<div class="box g">G</div>
<div class="box h">H</div>
<div class="box i">I</div>
<div class="box j">J</div>
</div>
根据第一个实例我们可以知道,在这个实例中,定义了一个5行7列的网格,每一列的宽度依次为100px 10px 100px 10px 100px 10px 100px,对于上图中就是黑色区域宽度为100px,白色区域宽度为10px,网格a~j的位置则是由对于网格线确定的。例如.i {grid-column-start: 1;grid-column-end: 2; grid-row-start: 5;grid-row-end: 6;}表示网格i的列起始线为1,列终止线为2,行起始线为5,行终止线为6,我们只需要改变单元格的行列起止线就可以改变单元格的位置。当然,我们也可以将上面的代码简写成下面的简写形式:
.i{
grid-column:1 / 2;
grid-row:5 / 6;
}
/*还可以简写为(行开始 / 列开始 / 行结束 / 列结束)*/
.i{
grid-area:5 / 1 / 6 / 2;
}
显示和隐示网格线
在上面的实例代码中,一个5行7列的网格,形成了6条行网格线,8条列网格线,这些网格线被称为显示网格线,现在,将上面的代码稍作修改
/*
.i {grid-column-start: 1;grid-column-end: 2; grid-row-start: 5;grid-row-end: 6;}
简写为
.i {grid-area: 5 / 1 / 6 / 2;}
.j {grid-column-start: 3;grid-column-end: 4; grid-row-start: 5;grid-row-end: 6;}
简写为
.j{grid-area:5/3/6/4}
*/
.i {grid-area: 5 / 1 / 6 / 8;}
.j {grid-area: 7 / 1 / 8 / 8;}
本实例只是在上一个实例的基础上修改了网格i和j的行列起止线,得到了上面的结果,在结果中我们可以看出,这是一个7行7列的网格,而我们定义的是一个5行7列的网格,其中最后两行并未定义,只是在为网格j画区域的时候超过了行网格线预设的显示网格线,因此,我们将超出的两条网格线称为隐示网格线。
参考资料
CSS Grid布局:网格单元格布局 https://www.w3cplus.com/css3/line-base-placement-layout.html