让我们接着来看网格布局
在之前的博文中,我介绍了如何使用线编号来排列元素,本篇博文则会全面探索这个基础特性如何工作。
当我们使用网格布局创建网格轨道的时候,网格线也会被同时创建。每条网格线都有对应的编号,而且编号的规则则是根据书写方向来决定的,例如像英语这种从左至右书写的语言中,列线1将位于网格的左侧。而在从右到左的语言中,列线1行将位于网格的右侧。之后我们会深入探讨书写模式和网格间的交互。
在下面这个非常简单的例子中,我使用了3行3列的布局,也就是说,在从上至下,从左至右这两个大方向上,将各存在4条网格线。
网格容器中有4个子元素。如果我们不定义它们的位置,它们便会按照自动定位规则布局。代码及效果如下
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 100px);
}
<div class="wrapper">
<div class="box1">One</div>
<div class="box2">Two</div>
<div class="box3">Three</div>
<div class="box4">Four</div>
</div>
我们可以使用线编号来控制元素在网格上的位置。仍以上面的布局结构为例,当我想让第一个元素从网格的最左边开始,占一个列轨道。在行轨道的占用上,则从行线1开始,延伸至行线4。那么我们写在class名为“box1”的css代码就应当如下:
.box1 {
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 4;
}
当你采取上面的方法为一些元素定位之后,剩下的元素会继续按照自动定位规则定位。
下面我将以同样的方法为剩下的三个网格元素进行定位。代码及效果如下
<div class="wrapper">
<div class="box1">One</div>
<div class="box2">Two</div>
<div class="box3">Three</div>
<div class="box4">Four</div>
</div>
.box1 {
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 4;
background-color: green;
}
.box2 {
grid-column-start: 3;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
background-color: red;
}
.box3 {
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 2;
background-color: blue;
}
.box4 {
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 3;
grid-row-end: 4;
background-color: yellow;
}
网格布局的一个优势是:无需给元素周围加上margin来阻止文档流自动填补空白,就能实现设计中的留白区域。
在网格布局中,grid-column-start 和 grid-column-end 属性可以合并为 grid-column,grid-row-start 和 grid-row-end 则合并为 grid-row。
让我们以缩写的方式对上面的CSS代码进行一下优化(背景色部分省略):
.box1 {
grid-column: 1 / 2;
grid-row: 1 / 4;
}
.box2 {
grid-column: 3 / 4;
grid-row: 1 / 3;
}
.box3 {
grid-column: 2 / 3;
grid-row: 1 / 2;
}
.box4 {
grid-column: 2 / 4;
grid-row: 3 / 4;
}
在上面的例子中,我指定了每个结束行线和列线,但实际上如果一个元素只延伸一个轨道的话,你可以省略 grid-column-end 或 grid-row-end 值。元素默认延伸一个轨道。所以在最开始的例子中,我们的CSS代码可以改写为这样:
.box1 {
grid-column-start: 1;
grid-row-start: 1;
grid-row-end: 4;
}
.box2 {
grid-column-start: 3;
grid-row-start: 1;
grid-row-end: 3;
}
.box3 {
grid-column-start: 2;
grid-row-start: 1;
}
.box4 {
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 3;
}
在使用 grid-column 和 grid-row 缩写时,对于那些只跨越了一个轨道的元素,则可以省略“/”和第二个值。所以我们的代码则可以改写为这样:
.box1 {
grid-column: 1 ;
grid-row: 1 / 4;
}
.box2 {
grid-column: 3 ;
grid-row: 1 / 3;
}
.box3 {
grid-column: 2 ;
grid-row: 1 ;
}
.box4 {
grid-column: 2 / 4;
grid-row: 3 ;
}
我们还可以使用 grid-area 属性 让上面例子中的代码更加简单:每个元素只定义一个属性 grid-area。值的顺序如下
对应代码如下:
.box1 {
grid-area: 1 / 1 / 4 / 2;
}
.box2 {
grid-area: 1 / 3 / 3 / 4;
}
.box3 {
grid-area: 1 / 2 / 2 / 3;
}
.box4 {
grid-area: 3 / 2 / 4 / 4;
}
我们也可以从行和块的结束线开始反方向计数,对于英语来说就是右端的列线和底端的行线。这些线会被记为 -1,然后你可以从这儿往前数,所以倒数第2条线会被记为 -2。要注意的是最后一条线是指显式定义网格的最后一条线,即由 grid-template-columns 和 grid-template-rows 定义的网格,并不把隐式定义网格的加入的行和列纳入考虑。
下面我将从右侧和低端开始布局,并把之前的例子翻转
代码及效果如下
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 100px);
}
.box1 {
grid-column-start: -1;
grid-column-end: -2;
grid-row-start: -1;
grid-row-end: -4;
background-color: green;
}
.box2 {
grid-column-start: -3;
grid-column-end: -4;
grid-row-start: -1;
grid-row-end: -3;
background-color: red;
}
.box3 {
grid-column-start: -2;
grid-column-end: -3;
grid-row-start: -1;
grid-row-end: -2;
background-color: blue;
}
.box4 {
grid-column-start: -2;
grid-column-end: -4;
grid-row-start: -3;
grid-row-end: -4;
background-color: yellow;
}
除了”起始线与结束线“的定位方法,你还可以使用”起始线与跨越轨道数量“的定位方法,写法如下
// 起始线/span跨越轨道数量
grid-row: 1 / span 3;
之前的代码可做如下更改
.box1 {
grid-column: 1;
grid-row: 1 / span 3;
}
.box2 {
grid-column: 3;
grid-row: 1 / span 2;
}
.box3 {
grid-column: 2;
grid-row: 1;
}
.box4 {
grid-column: 2 / span 2;
grid-row: 3;
}
或者“结束线与跨越轨道数量”,写法如下
// span跨越轨道数量/结束线
grid-row: span跨越轨道数量 / 4;
示例:
.box1 {
grid-column: 1;
grid-row: span 2 / 4;
background-color: green;
}