CSS Grid布局:合并单元格布局

CSS Grid布局:网格单元格布局》一文中经过一些简单的实例介绍了如何给容器定义网格,而且怎么使用网格线或者网格区域来实现单元格这样的简单的布局。在文章结尾之处也提到过,这样的单元格如同表格同样,仅仅一个个独立的单元格是没法知足一些复杂的Web布局,咱们须要将多个单元格合并在一块儿,拼装成一个稍为复杂一点的布局。简单点说,就是由单元格慢慢过渡到具备合并单元格的布局(在脑海中想一想曾经爱过的table)。css

那么接下来咱们要介绍的是如何使用CSS Grid Layout实现一些更有意思的布局。html

期待中的布局...

在脑海中有不少种布局效果,那咱们先来看一种常见的,简单的布局模板,以下图所示:css3

布局模板.png

上图也是这一章须要实现的一种布局方式,就将其称为网格的合并单元格布局,由于他和表格中的合并单元格是很是的类似。segmentfault

你们是否还记得,在《CSS Grid布局:网格单元格布局》一文中经过网格线的grid-column-startgrid-column-endgrid-row-startgrid-row-end(或者grid-column: start / endgrid-row: start / end)能够很是方便的实现单元格的布局,那么这种方式一样能够运用于合并的单元格布局中。如此一来,若是咱们须要实现上图展现的布局,就能够给每一个子元素设置网格线,而后划分出各自的占位区。来看看其对应的网格线:浏览器

网格线.png

有了这样的示意图,我想要实现这个布局对于你们来讲并非一件复杂的事情。接下来咱们经过实例来演示。app

基于网格线实现单元格合并

从示图中不难发现:布局

  • A区(.a)跨越了三列和两个列间距,对应网格布局中,他占了五个网格,从网格线上来划分,他是列网格线line1line6和行网格线line1line2圈起的空间
  • C、D、E、G和H几个区与之前介绍的单元格并没有不一样之处,对于的网格线能够看上面的网格线展现示意图
  • F区(.f)跨越了两列和一个列间距,对应网格布局中,他占了三个网格,从网格线上来划分,他是列网格线line1line4和行网格线line5line6圈起的空间
  • I区(.i)和F区相似,只不过他是列网格线line3line6和行网格线line7line8圈起的空间
  • J区(.j)和A区相似,只不过他是列网格线line1line6和行网格线line9line10圈起的空间
  • B区(.b)和前面几个区都有点不同,他是将行合并在一块儿,跨越了网格中全部的行,从网格线上来划分,他是列网格线line7line8和行网格线line1line10圈起的空间

从外观上看,这跟平时看到的两列布局很是的类似。不一样之处是这里经过网格来实现。来看看具体代码:spa

HTML
<div class="wrapper">
  <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>
CSS
body {
  padding: 50px;
}
.wrapper {
  display: grid;
  grid-template-columns: 100px 10px 100px 10px 100px 10px 100px;
  grid-template-rows: auto 10px auto 10px auto 10px auto 10px auto;
}
.box {
  background-color: #444;
  color: #fff;
  font-size: 150%;
  padding: 20px;
  text-align: center;
}
.a{
  grid-column: 1 / 6; 
  grid-row: 1 / 2;
}
.b {
  grid-column: 7 / 8; 
  grid-row: 1 / 10; 
  background: orange;
}
.c { 
  grid-column: 1 / 2; 
  grid-row: 3 / 4;
}
.d { 
  grid-column: 3 / 4; 
  grid-row: 3 / 4;
}
.e { 
  grid-column: 5 / 6; 
  grid-row: 3 / 4;
}
.f { 
  grid-column: 1 / 4; 
  grid-row: 5 / 6;
}
.g {
  grid-column: 5 / 6; 
  grid-row: 5 / 6;
}
.h {
  grid-column: 1 / 2; 
  grid-row: 7 / 8;
}
.i {
  grid-column: 3 / 6; 
  grid-row: 7 / 8;
}
.j {
  grid-column: 1 / 6; 
  grid-row: 9 / 10;
}

效果以下:code

基于网格线合并单元格.png

在线案例htm

从效果图中,不难发现,虽然在B区经过网格线定义了跨行:

.b {
  grid-column: 7 / 8; 
  grid-row: 1 / 10; 
  background: orange;
}

但浏览器实际解析并非跟咱们想象的同样。为何跨行没有效果呢?具体是什么缘由,说实在的,我也不知道,或许有一天会更正这个问题。那么有没有方法能解决呢?咱们先继续往下看吧。或许你能找到你须要的答案。

基于网格线使用关键词span实现单元格合并

在CSS Grid Layout布局中除了使用网格线合并单元格以外,还可使用关键词span来实现单元格合并。接下来的实例,将使用span关建词完成上例同样的效果。

.wrapper {
  display: grid;
  grid-template-columns: 100px 10px 100px 10px 100px 10px 100px;
  grid-template-rows: auto 10px auto 10px auto 10px auto 10px auto;
}
.a{
  grid-column: 1 / span 5; 
  grid-row: 1;
}
.b {
  grid-column: 7; 
  grid-row: 1 / span 9; 
  background: orange;
}
.c { 
  grid-column: 1; 
  grid-row: 3;
}
.d { 
  grid-column: 3; 
  grid-row: 3;
}
.e { 
  grid-column: 5; 
  grid-row: 3;
}
.f { 
  grid-column: 1 / span 3; 
  grid-row: 5;
}
.g {
  grid-column: 5; 
  grid-row: 5;
}
.h {
  grid-column: 1; 
  grid-row: 7;
}
.i {
  grid-column: 3 / span 3; 
  grid-row: 7;
}
.j {
  grid-column: 1 / span 5; 
  grid-row: 9;
}

实现的效果同样:

基于网格线合并单元格.png

在线案例

自定义网格线名称

前面的示例,都是使用默认的网格线名称来制做网格布局,其实在CSS Grid Layout模块中还提供了自定义网格线名称,而后使用定义好的名称来制做网格布局。在CSS Grid Layout自定义网格线名称都放置在()内。好比在下面的示例中,定义了列第一网格线名称为col1-start(对应的列网格线line1),而后后面紧跟第一列的轨道宽度100px,而后就是第一列后面的网格线col1-end(对应的列网格线line2)。行网格线也是相似。以下图所示:

自定义网格线名称.png

在网格定义网格线的方式以下:

.wrapper {
  display: grid;
  grid-template-columns: (col1-start) 100px (col1-end) 10px (col2-start) 100px (col2-end) 10px (col3-start) 100px (col3-end) 10px (col4-start) 100px (col4-end);
  grid-template-rows: (row1-start) auto (row1-end) 10px (row2-start) auto (row2-end) 10px (row3-start) auto (row3-end) 10px (row4-start) auto (row4-end) 10px (row5-start) auto (row5-end);
}

写个实例,经过自定义的网格线实现上例同样的网格布局效果:

.wrapper {
  display: grid;
  grid-template-columns: (col1-start) 100px (col1-end) 10px (col2-start) 100px (col2-end) 10px (col3-start) 100px (col3-end) 10px (col4-start) 100px (col4-end);
  grid-template-rows: (row1-start) auto (row1-end) 10px (row2-start) auto (row2-end) 10px (row3-start) auto (row3-end) 10px (row4-start) auto (row4-end) 10px (row5-start) auto (row5-end);
}
.a{
  grid-column: col1-start / col3-end; 
  grid-row: row1-start;
}
.b {
  grid-column: col4-start / col4-end; 
  grid-row: row1-start / row5-end; 
  background: orange;
}
.c { 
  grid-column: col1-start; 
  grid-row: row2-start;
}
.d { 
  grid-column: col2-start; 
  grid-row: row2-start;
}
.e { 
  grid-column: col3-start; 
  grid-row: row2-start;
}
.f { 
  grid-column: col1-start / col2-end; 
  grid-row: row3-start;
}
.g {
  grid-column: col3-start; 
  grid-row: row3-start;
}
.h {
  grid-column: col1-start; 
  grid-row: row4-start;
}
.i {
  grid-column: col2-start / col3-end; 
  grid-row: row4-start;
}
.j {
  grid-column: col1-start / col3-end; 
  grid-row: row5-start;
}

效果和预期的同样,能够打示演示案例查看效果。

在线案例

自定义网格线配合关键词span合并单元格

上面那种自定义网各线的方法好是好,但也有一个问题,若是网格线少,仍是蛮方便的,不过网格一多,网格线也多起来,每条网格线都定义名称是否是太费时费力了。其实在CSS Grid Layout中不须要这么作,你彻底能够给网格线定义相同的名称,而后使用关键词span添加到特定的目标网格线。这种方法对于建立一些复杂的网格(包括多个网格与列间距)是很是方便的。

在实际使用中,能够在网格内容轨道前的网格线都定义为col,而在列间距轨道前的网格线都定义为gutter。在调用时,可使用col <line number>来指定开始的网格线,配合关键词span <number of lines of that name>来指写网格的跨度。这样说或许有些搞不明白,咱们来看一个简单的示例,好比说咱们要实现下图网格效果:

自定义网格线名称.png

看看代码要怎么写,才能完成上图的网格效果:

.wrapper {
  display: grid;
  grid-template-columns: (col) 100px (gutter) 10px (col) 100px (gutter) 10px (col) 100px (gutter) 10px (col) 100px (gutter) 10px (col) 100px (gutter) 10px (col) 100px (gutter); 
  grid-template-rows: (row) auto (gutter) 10px (row) auto (gutter) 10px (row) auto (gutter) 10px (row) auto;
}

.a{
  grid-column: col / span gutter 2; 
  grid-row: row;
}
.b {
  grid-column: col 3 / span gutter 2; 
  grid-row: row;
}
.c { 
  grid-column: col 5 / span gutter 2; 
  grid-row: row;
}
.d { 
  grid-column: col / span gutter 3; 
  grid-row: row 2;
}
.e { 
  grid-column: col 4 / span gutter 3; 
  grid-row: row 2;
}
.f { 
  grid-column: col / span gutter 2; 
  grid-row: row 3;
}
.g {
  grid-column: col 3 / span gutter 1; 
  grid-row: row 3;
}
.h {
  grid-column: col 4 / span gutter 2; 
  grid-row: row 3;
}
.i {
  grid-column: col 6 / span gutter 1; 
  grid-row: row 3;
}
.j {
  grid-column: col  / span gutter 6; 
  grid-row: row 4;
}

效果以下:

自定义网格线名称.png

在线案例

repeat关键词

在上例中,不难发现列和行都有不少重复的,好比:列网格线有六个(col) 100px (gutter) 10px,而行网格线有四个(row) auto (gutter) 10px。其实在CSS Grid Layout没有必要这么痛苦,他提供了一个关键repeat,彻底可使用repeat来让你的代码变得更简洁。

使用repeat的代码以下:

.wrapper {
  display: grid;
  grid-template-columns:repeat(6, (col) 100px (gutter) 10px); 
  grid-template-rows: repeat(4, (row) auto (gutter) 10px );
}

你将看到效果:

在线案例

是否是如出一辙呀。是否是变得轻松多了。

网格区域制做合并单元格

在上一节中,介绍了网格区域制做单元格,其实根据网格区域的定义,也可使用网格区域实现单元格的效果。回到文章第一个示例,使用网格区域,只须要这样写,就能够轻松实现所须要的效果:

.wrapper {
  display: grid;
  display: grid;
    grid-template-columns: 100px 10px 100px 10px 100px 10px 100px;
    grid-template-rows: auto 10px auto 10px auto 10px auto 10px auto;
}
.a{
  grid-area: 1 / 1 / 2 / 6;
}
.b {
  grid-area: 1 / 7 / 10 / 8;
  background: orange;
}
.c { 
  grid-area: 3 / 1 / 4 / 2; 
}
.d { 
  grid-area: 3 / 3 / 4 / 4;
}
.e { 
  grid-area: 3 / 5 / 4 / 6;
}
.f { 
  grid-area: 5 / 1 / 6 / 4;
}
.g {
  grid-area: 5 / 5 / 6 / 6;
}
.h {
  grid-area: 7 / 1 / 8 / 2;
}
.i {
  grid-area: 7 / 3 / 8 / 6;
}
.j {
  grid-area: 9 / 1 / 8 / 6;
}

效果以下:

在线案例

模拟合并行

从上面演示的众多示例能够得知,在CSS Grid Layout中合并行并无像合并列来得那么简单。换句话说,要实现下图的效果,到目前为止仅使用CSS Grid Layout的网格线或者网格区域是没法实现的。

布局模板.png

或许你们会说,抛开浏览器的兼容性问题,若是我真要实现上图的布局风格,怎么破呢?我尝试了一下,若是须要强制实现上图效果,能够在.b容器中添加一段代码:

.b {
  grid-area: 1 / 7 / 10 / 8;
  background: orange;
  height: 100%;
  box-sizing:border-box;
}

若是就模拟出上图须要的效果。

在线案例

总结

单元格的合并对于实现一个复杂的网格布局是不可或缺的,那么这篇文章主要向你们介绍了如何使用网格线制做网格的合并效果。实现方法有不少种,能够用网格线来划分,也可使用关键词span来跨列,固然还可使用repeat来减小网格线定义的重复工做。除了网格线以外,还可使用网格区域来实现合并单元格的效果。不知道你掌握了几种方法呢?

via w3cplus

相关文章
相关标签/搜索