果冻公开课第十一课:CSS强大的布局系统 Grid

果冻公开课第十一课:CSS强大的布局系统 Grid

      CSS的布局方式,一直以来都不够完善,无论是table,还是float,还是position或者是inline-block,都更像是在残缺不全的设计基础上的hack方式。

        flex已经在某种程度上对布局有所改变,但是只解决了一维布局的问题。

        那么有没有更好的方式,来跳出原本CSS布局的限制,用更简单和容易理解的方式完成复杂的布局呢?

文字解析:

 

        CSS的布局本质上是从上到下,从左到右的书写顺序,以现在的角度来看,这种布局的理念并未考虑到整体,也很难去实现居中,对齐,分布等。

       布局的本质到底是什么?怎么去安排元素占据的空间、顺序,可否从别的领域中学习新的布局方式呢?

       周星驰有一部电影,叫做《大内密探零零发》,其中一段关于骚阳阳的情节是这样的:

       把一个平面,分成网格,横向和竖向两种轴向完美切割平面,就可以很精准的确定某块区域。这和我们的经纬度是不是也很相似?中国象棋和围棋的棋谱也是这种思路啊。

所以一个大胆的设想就是,能否把网页切分,变成无数小格子,像我们小时候的作业本一样,然后,定位和布局的时候,直接指定一个元素在第几格,占据多少行多少列。

果冻公开课第十一课:CSS强大的布局系统 Grid

 

       我们按照这种思路走下去,要切分网格,首先要告诉浏览器,接下来的布局是新一代的网格布局方式。好在display可以约定设置一个新的值来处理:grid

.container {

    display: grid;

}

如果是内联,我们就用inline-grid

.container {

    display: inline-grid;

}

既然要画格子,每一条线的间距是默认,还是交给前端去自由设置?考虑到布局的多样性,干脆提供一种自由设置网格的方式:

.container {

    grid-template-columns: 40px 50px auto 50px 40px;

    grid-template-rows: 25% 100px auto;

}

通过新增加的两个属性,grid-template-column和grid-template-rows,我们可以让前端自由在容器内切分空间了,是不是很开心?

emm,如果有小调皮想要说,要是线太多会数错怎么办?

满足你!可以让你任意指定每一条线的名字! 

.container {

    display: grid;

    grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];

    grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];

}

 

额,你觉得这样的线要是多重复几遍会超级麻烦。。。?好的吧,懒毕竟是程序员的第一推动力,那我们再增加一种语法糖,简洁地描述一下:

.container {

    grid-template-columns: repeat(2, 100px 20px);

}

怎么样,是不是完美的支持你在容器里画各种横线竖线了。不过第二个问题又来了,线画好之后,又该怎么去布置元素呢?

果冻公开课第十一课:CSS强大的布局系统 Grid

怎么布置元素

 

这种如果太复杂,就用起止位置来代替

果冻公开课第十一课:CSS强大的布局系统 Grid

起止位置来代替

这样相当于拿起画笔,可以随意指定网格中的元素占据位置。

格子画好了,定位和占位也有了,开心!

等等,好像还没完事儿,对齐怎么处理??

emmm,对我们还忘记了,怎么对齐。

没格子之前,常用的对齐就是左 ,右对齐,上对齐,下对齐和居中对齐。有了网格之后,我们可以支持:

  1. 起始边缘对齐(例子)

container {

    justify-items: start;

}

2.结束边缘对齐(例子)

container {

    justify-items: end;

}

3.居中对齐(例子)

.container {

    justify-items: center;

}

4.填满单元格(例子)

.container {

    justify-items: stretch;

}

除了行上对齐外,还能指定列上的对齐,同样是

  1. 起始边缘对齐(例子)

.container {

  align-items: start;

}

2.结束边缘对齐(例子)

.container {

    align-items: end;

}

3.居中对齐(例子)

.container {

    align-items: center;

}

4.填满单元格(例子)

.container {

    align-items: stretch;

}

除了指定网格内所有元素的对齐外,还能单独指定某一个元素的对齐:

单个元素的行对齐也是四种方式,

  1. 起始边缘对齐(例子)

.item-a {

    justify-self: start;

}

2.结束边缘对齐(例子)

.item-a {

    justify-self: end;

}

3.居中对齐(例子)

.item-a {

    justify-self: center;

}

4.填满单元格(例子)

.item-a {

    justify-self: stretch;

}

单个元素的列对齐同样是四种方式,

  1. 起始边缘对齐(例子)

.item-a {

   align-self: start;

}

2.结束边缘对齐(例子)

.item-a {

   align-self: end;

}

3.居中对齐(例子)

.item-a {

   align-self: center;

}

4.填满单元格(例子)

.item-a {

   align-self: stretch;

}

对齐也搞定了,好像还差点什么??

emmm看起来有点满,元素之间还少了点间隙,怎么设置间隙呢?

没格子之前我们都是用margin,现在有网格线了,可以直接设置网格线的粗细大小,也就等同于元素之间的间隙。

果冻公开课第十一课:CSS强大的布局系统 Grid

设置元素间隙

这样,先画出来格子,再定位元素和占据的空间,最后指定布局方式,是不是就可以在我们的世界里为所欲为了?

我们来看几种常见的布局:

一、左右固定中间自适应

以前,这需要使用margin,float, position 解决,圣杯布局是一个比较好的解决方案。grid 布局相比过去的方式简单许多,只需要在 container 上设置 grid-template-columns: 100px auto 100px。

.container { 

    display: grid; 

    grid-template-columns: 100px auto 200px; 

}

二、复杂布局

如果说前一种布局还能用flex解决,而这种复杂布局就有些困难了。grid布局可以在 container 上使用 grid-template-areas,在 item 上设置 grid-area 属性来设置。

果冻公开课第十一课:CSS强大的布局系统 Grid

复杂布局设置

嗯,有没有觉得之前的布局太复杂了?现在我们给我们伟大的创意起个名字吧,我们把它叫做:Grid

既然方案有了,前端er就像是设计师,可以遵循这种方案来完成代码。各大浏览器厂商就需要遵守这种设计规范来实现它,好在现在大多数浏览器都支持了grid,所以你可以开心的使用grid的来完成成布局了。(展示出来支持浏览器最低版本)

甩开过去的束缚才能创造新世界,你有没有比网格布局更好的布局方案?