CSS-Grid网格布局模块探索之旅

此篇想法总访问 15 次,今日访问 2 次。

CSS Grid网格布局让开发者能比以往任何时候都更加灵活的控制结构。网格布局使开发者只需要设置几个属性即可轻松的将网页切割成行与列,而且这种布局还允许我们使用CSS任意调整网格中元素的位置与大小——在不改变HTML结构的前提下。

定义网格

伴随着CSS3中这一新模块规范的制定,display属性也增加了一个新的属性——grid,只要你将任何元素的display属性设置为grid,那它就变成了一个网格容器,它的子元素们就成为了网格项(grid items)。

OK!为了创建一个3*3的网格布局,我们就以Tic-Tac-Toe游戏为例来开始入门CSS Grid之旅,首先,先搭建好HTML结构:

<div class="game-board">
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>

正如你所看到的,我们希望*.game-board这一div元素就是网格容器,.box*这些div元素们就是网格项,现在利用CSS技术将他们按每行三列的布局方式创建网格布局:

.game-board{
    display: grid;
    grid-template-rows: 50px 50px 50px;
    grid-template-columns: 50px 50px 50px;
}

这里,我们用到了两个新的属性,grid-template-rows属性允许你指定有多少行和每一个行在网格中的大小,我想另一个属性你也能猜到怎么用了吧。

grid-template-colums属性允许你指定网格中有多少行并且每一列的大小。你可以使用任何单位来制定网格项的大小,包括像素px,百分比%和新的单位fr,fr就是我接下来要介绍的。

fr单位(fraction)

fr是专门为网格布局定义的单位,它帮助你摆脱计算百分比并且按权重为可用的网格空间分配网格项。

举个例子,如果你这样为网格容器写css样式规则:

grid-template-row:2fr 3fr;

如此一来,对于你的网格容器,首先——切分成两行,然后每一个网格项的大小将按权重的比值分配。

现在已经有两行了:第一行占垂直空间大小的2/5,第二行站垂直空间总大小的3/5,就是这么简单。

回到我们之前的Tic-Tac-Toe游戏,采用fr单位替换px单位,想一想,我们需要3行3列,因此,我们只需要将3个200px替换为3个1fr:

.game-board{
    display: grid;
    grid-template-rows: 1fr 1fr 1fr;
    grid-template-columns: 1fr 1fr 1fr;
}

repeat()函数

在一些情况下,我们需要创建很多行和很多列,适用grid-template属性但一个一个的指定行列数是很没效率的。幸运的是,有了repeat函数就能方便的指定行列数量与行列大小。只需要传递两个参数,第一个参数是迭代次数,第二个参数是大小。让我们使用repeat函数重写前一个例子吧:

.game-board{
    display: grid;
    grid-template-rows: repeat(3, 1fr);
    grid-template-columns: repeat(3, 1fr);
}

上面的CSS规则和下方的相同:

.game-board{
    display: grid;
    grid-template-rows: 1fr 1fr 1fr;
    grid-template-columns: 1fr 1fr 1fr;
}

grid-template 属性

对于grid-template-rows和grid-template-columns属性分开写显得啰嗦,我们可以将它们合并到一个符合属性中——grid-template,这是他的语法:

grid-template: rows / columns;

使用这个符合属性,我们之前的例子又可以简写为:

.game-board{
    display: grid;
    grid-template: repeat(3, 1fr) / repeat(3, 1fr);
}

看!只需要两行你就可以创建一个3*3的网格布局。

X
0
0
0
X
0
0
X
X

网格线网格单元格与网格轨道

网格线指的是每一行或每一个的侧边,一种网格线用来将垂直方向分成很多列,另一种网格线用于将水平方向分割成很多行。意思就是说,那我们前面的例子作比,例子中有四条垂直线和四条水平线存在于行与列之间与整个网格容器的外侧。

当我们想要将网格项从一个位置移动到另外一个位置,网格线就变得非常有用。

一条网格轨道指的是两条网格线之间的空间,或者可以认为网格轨道指的是一行或一列。

网格单元格,类似于表格单元格,介于两条垂直网格线与两条水平网格线相交之间所形成的空间。是网格容器最小的单位。

定位网格项

我将之前的例子的网格中的X和O替换为了数字,方便演示网格布局中的网格项如何灵活的改变自身位置:

说说我们目前的任务吧,我想要移动第六个盒子至第二个盒子的位置,在不使用网格布局的前提下,想要实现这项任务几乎不可能,至少对我来说在不改变HTML结构的前提下不可能。但是有了新的网格布局模块,改变盒子的位置轻而易举。

想要将第6个盒子移动至第2个盒子的位置,我们需要描述清楚第二个盒子现在的位置,这个时候,网格线的编号就起到了作用——第二个盒子位于垂直方向上的第2、3网格线之间;水平方向上的第1、2网格线之间。现在,我们将这些信息设置给第6个盒子即可。在这之前先来认识下这4个属性:

grid-column-start
grid-column-end
grid-row-start
grid-row-end

前两个属性定义了垂直方向上的起、止网格线编号,后两个属相定义了水平方向上起、止网格线的编号,现在可以把这些CSS规则应用到第6个盒子上了:

.box:nth-child(6){
    grid-row-start: 1;
    grid-row-end: 2;
    grid-column-start: 2;
    grid-column-end: 3;
}

同样的,上面的CSS样式规则也有两种简写形式:

.box:nth-child(6){
    grid-row: 1 / 2;
    grid-column: 2 / 3;
}

另外,不得不提及 grid-area 属性。这个属性是上面提到的四个属性的简写形式,格式如下:

grid-area: <row-start> / <column-start> / <row-end> / <column-end>;

现在,我们的例子看起来是这个样子的:

.box:nth-child(6){
    grid-area: 1 / 2 / 2 / 3;
}

上方的CSS规则书写形式还可以继续缩减。因为我们需要移动的第6个盒子只占了一个网格项,所以我们只需要指定行与列的开始起始网格线即可,不需要指定行与列的结束网格线:

.box:nth-child(6){
    grid-area: 1 / 2;
}

如果我们想让第六个盒子把第2、3个盒子都占上,那也很容易办到,只需要添加 column-end 的值加1即可。

.box:nth-child(6){
    grid-area: 1 / 2 / 2 / 4;
}

你还可以使用 span 关键词外加一个表示轨道数的数字来指定结束的网格线编号,第六个盒子占据了两列一行。

.box:nth-child(6){
    grid-area: 1 / 2 / 2 / span 2;
}

为Grid Area命名

同样可以为 grid-area 属性赋予一个名称,方便后续使用 grid-template-areas 属性来定位。让我们创建一个简单的 面包加黄油 布局——header在最顶部,nav,main,aside在中间,footer在最下方,下方市HTML结构:

<div class="container">
  <header></header>
  <nav></nav>
  <main></main>
  <aside></aside>
  <footer></footer>
</div>

我们需要使用 grid-area 为每一个区域起一个名字,就像这样:

header{
  grid-area: header;
  background-color: #9b59b6;
}
nav{
  grid-area: nav;
  background-color: #3498db;
}
main{
  grid-area: main;
  background-color: #2ecc71;
}
aside{
  grid-area: aside;
  background-color: #f1c40f;
}

footer{
  grid-area: footer;
  background-color: #1abc9c;
}

使用 grid-template-areas 属性指定每一个区域的那一行与列需要横跨一个区域,可以这样做:

.container{
      display: grid;
      grid-template-rows: 1fr 5fr 1fr;
      grid-template-columns: 2fr 5fr 3fr;
      grid-template-areas:
        "header  header  header"
        "nav     main    aside"
        "footer  footer  footer";
      grid-gap: .75em;
}

注意,header和footer两个单词重复了三次。header和footer将横跨三个网格行,细心的你会发现这儿又出现的新的属性: grid-gap,意思就是在每两个网格区域之间添加空白间隔,你可以使用 grid-row-gap和grid-column-gap为行和列指定不同的间隔数值,运行结果就是下面的样子,很神奇吧:

浏览器Supported

截至目前为止,浏览器都能很好的支持CSS网格布局,根据caniuse.com网站的描述,所有主流浏览器都支持CSS网格布局,除了IE11需要-ms-的前缀,Opear Mini浏览器还不支持。

结语

CSS网格布局允许我们快速创建控制灵活的布局,在上面的实战中,我们学习了如何使用CSS网格定于网格布局,还有新的单位 fr,重复repeat()函数,和一写用于指定网格表现行为的属性。我们还学习了如何在网格容器内使用网格线和网格名称定位网格项。但这一切只是个开始,在接下来的实战中,我们将更加深入的了解CSS Grid网格布局。


本篇译完 ·END·

原文链接:Getting Started with CSS Grid Layout

发布日期 » 2017年12月4日 周一
原创声明 » 请勿复制转载,谢谢配合。
Airglass.js核心库
JavaScript核心概念
硬件编程、Arduino
文档翻译计划
微信开发
前端脚手架
运维
可视化
生活自有“道”理
视觉设计、用户体验
陈帅华的微信二维码