前端开发者学堂 - fedev.cn

CSS3 Grid Layout

发布于 大漠

Web页面的布局,我们常见的主要有“浮动布局(float)”、“定位布局(position)”、“行内块布局(inline-block)”、“CSS3的多栏布局(Columns)”、“伸缩布局(Flexbox)”以及“网格布局(Grids)”等,在众多布局方法中,大家最为熟悉的就是浮动布局和网格布局,并且使用不同的细节能得到不同的布局效果。虽然这些布局能让大家实现常见的布局效果,但在实际中还是存在不少的问题,比如说浏览器的兼容性、修改显示顺序需要调整文档结构等。那么有没有什么更好的,更理想的布局方法?这也就是今天要和大家一起学习的一个布局模式——CSS3 Grid Layout

今天说的CSS3 Grid Layout并不是我们以前接触的一些网格,例如960gs。这个网格是CSS3为布局新添加的一个布局模块。下面我们根据W3C官网发布的内容,先了解一些CSS3 Grid Layout知识。

摘要

CSS3 Grid Layout是一个新的模块,这个模块主要定义一个二维网格布局系统,用来优化用户界面设计。在这个网格布局模块中,网格容器的所有子元素可以在一个灵活的或者固定的了布局网格中定位到任意槽中。

CSS3 Grid Layout的简介

网格布局特性主要是针对于Web应用程序的开发者。可以用这个模块实现许多不同的布局。网络布局可以将应用程序分割成不同的空间,或者定义他们的大小、位置以及层级。

就像表格一样,网格布局可以让Web设计师根据元素按列或行对齐排列,但他和表格不同,网格布局没有内容结构,从布使各种布局不可能与表格一样。例如,一个网格布局中的子元素都可以定位自己的位置,这样他们可以重叠和类似元素定位。

此外,没有内容结构的网格布局有助于使用流体、调整顺序等技术管理或更改布局。通过结合CSS的媒体查询属性,可以控制网格布局容器和他们的子元素,使用页面的布局根据不同的设备和可用空间调整元素的显示风格与定位,而不需要去改变文档结构的本质内容。

CSS3 Grid Layout背景与前景

做为一个网站从简单的文当档演变为复杂的文档、应用程序,用于文档布局的方法,例如浮动“float”,未必就适合应用程序的布局。通过结合使用表格、javascript或仔细测量浮动元素,设计师发现了变通的方法来实现所需的布局。布局要适应可用空间往往都是很脆弱的,这样给人感觉布局受到了空间的制约。作为一个替代方案,设计师们采用一个固定的布局,这样在屏幕的变化之下利用可用的空间进行布局的调整。

网格布局将可以解决这些问题。它提供了一种机制,设计师可以使用一组可预知标准方案将可用的空间用列或行来布局。设计师可以精确定位和为元素创建精确的尺寸,应用到网格区域。下图展示的就是一个可以用网格实现的基本布局。

CSS3 Grid Layout

调整布局到可用空间

网格布局在网页中可以使用智能回流元素(Intelligently Reflow Elements)。下图表示了一个游戏与五大区域的布局:游戏标题、统计区域、游戏主面板区域、得分区域和控制区域:

CSS3 Grid Layout

作者将游戏区域划分为:

  • 数据统计区域总是会显示在游戏标题下面。
  • 游戏主面板区域出现在数据统计和标题区域的右边。
  • 顶部的游戏标题和游戏主面板应该对齐。
  • 当游戏已经达到最底高度的时候,游戏主面板的底部和数据统计区域底部对齐,否则游戏面板将会扩展到屏幕可用空间。
  • 得分区域应该和游戏数据统计的列对齐,而游戏的控制面板集中放置在游戏主面板的下面。

设计师可以使用网格布局来替代使用脚本来控制元素的绝对定位、宽度和高度的方案,如下图所示:

CSS3 Grid Layout

下面的例子展示了一个设计师如何实现所有的大小、位置和对齐的规则声明。

注:在每个不同的场景中,有多种方法来指定网格的结构和大小以及网格项目的大小。这个例子说明了设计师通过在网格容器(grid container)上定义网格定义行(grid definition rows)网格定义列(grid definition columns)属性各在网格项目(grid item)上定义网格行(grid row)网格列(grid columns)为每一个网格项目(grid item)定义位置和空间。

HTML结构

<div id="grid">
  <div id="title">Game Title</div>
  <div id="score">Score</div>
  <div id="stats">Stats</div>
  <div id="board">Board</div>
  <div id="controls">Controls</div>
</div>   

CSS代码

#grid {
  display: grid;
  background-color: orange;

  /* 分为两列: 
   * 第一列尺寸由内容大小控制
   * 第二列使用剩余空间,但大小从不会小于游戏主机板和控制区域最小宽度
   * 游戏主面板和游戏控制区域占在第二列
   */
  grid-definition-columns: auto minmax(min-content, 1fr);

  /* 三行: 
   * 第一行和最后一行的大小根据内容决定
   * 中间一行可以使用剩余空间,但从来不会小于游戏主面板的最小高度
   */
  grid-definition-rows: auto minmax(min-content, 1fr) auto;
}

/*游戏的每一部分都是通过网格线来定义的,每个部分都在其占的行中,如果哪个部分占有的行数多于一行,需要使用跨行来决定*/
#title{ 
  grid-column: 1; 
  grid-row: 1 ;
  background-color: red;
}
#score{ 
  grid-column: 1; 
  grid-row: 3;
  background-color:green;
}
#stats{ 
  grid-column: 1; 
  grid-row: 2; 
  justify-self: start ;
  background-color:#e9f;
}
#board{ 
  grid-column: 2; 
  grid-row: 1 / span 2; 
  background-color: #ccc;
}
#controls { 
  grid-column: 2; 
  grid-row: 3; 
  align-self: center;
  background-color: yellow;
}   

效果

CSS3 Grid Layout

查看在线案例

特别声明,请使用IE10+浏览器浏览DEMO效果。后面所有示例都只能在IE10+浏览器下才会有效果。

继续前面的例子,设计师希望自己的布局能在传统电脑显示器、手持设备或平板电脑中,都能很好的适应可用空间。同时在手持设置中,应该还要让页面能在设备的竖屏(portrait)和横屏(landscape)都能得到较完全美的显示。如下图所示:

CSS3 Grid Layout

竖屏显示布局效果。

CSS3 Grid Layout

横屏显示布局效果

通过网格布局和媒体查询的结合,设计师不需要修改任何文档结构就可以重新排列元素布局的顺序,达到理想的布局效果。

在上例的基础上做一些调整,使用网格布局空间名称的能力,重新为网格定义名称。

@media (orientation: portrait) {
  #grid {
    display: grid;

    /* 使用grid-template定义行、列和区域
     * 每个字符串定义行
     * 每个单词定义区域
     * 字符串中的单词数量确定了列数
     * 每个字符串中的单词数量必须相同 */

    grid-template: "title stats"
                   "score stats"
                   "board board"
                   "ctrls ctrls";

    /* 列和行创建了模板
     * 模板属性可以指定一个分级功能
     * 模板属性可以定义网格的列与网格行 */

    grid-definition-columns: auto minmax(min-content, 1fr);
    grid-definition-rows: auto auto minmax(min-content, 1fr) auto;
  }
}

@media (orientation: landscape) {
  #grid {
    display: grid;

    /* Again the template property defines areas of the same name, 
     * but this time positioned differently to better suit a 
     * landscape orientation. */
    grid-template: "title board"
                   "stats board"
                   "score ctrls";

    grid-definition-columns: auto minmax(min-content, 1fr);
    grid-definition-rows: auto minmax(min-content, 1fr) auto;
  }
}

/* The grid-area property places a grid item into a named 
 * region (area) of the grid. */
#title    { grid-area: title }
#score    { grid-area: score }
#stats    { grid-area: stats }
#board    { grid-area: board }
#controls { grid-area: ctrls }

非常遗憾的是到目前还没有浏览器支持grid-template属性,不过将来会支持的。这将是广大前端人员的福音。因为有了他布局不在是头痛的事情。

元素的网格分层

先来看下面一张滑块制作的示意图:

CSS3 Grid Layout

整个控件有六个部分。下标(lower-label)和上标(upper-label)和左边缘的控制都左对齐。滑块的轨道跨列了两个标签之间。中间的滑块可以控制下填充(lower-fill)和上填充(upper-fill)的大小。而且给滑块(thumb)设置了一个固定的大小。

在没有介绍网格布局之前,设计师们喜欢使用绝对定位来布局,通过控制每个元素的宽度和高度来控制每个元素的大小,然后通过确定每个元素的顶端和左边的坐标来实现上面的效果。利用网格布局,设计师可以根据“grid-definition-columns”给网格容器定义的位置,让中间滑块根据不同网格容器定义的网格列来实现不同的位置。

<div id="grid">
  <div id="lower-label">Lower Label</div>
  <div id="upper-label">Upper Label</div>
  <div id="track">Track</div>
  <div id="lower-fill">Lower Fill</div>
  <div id="upper-fill">Upper Fill</div>
  <div id="thumb">Thumb</div>
</div>   

实现的样式代码:

#grid {
  display: -ms-grid;
  -ms-grid-definition-columns:
    "start"        auto
    "track-start"  0.5fr
    "thumb-start"  auto
    "fill-split"   auto
    "thumb-end"    0.5fr
    "track-end"    auto
    "end";
}

#lower-label { 
  -ms-grid-start: "start";
}
#track { 
  -ms-grid-column: "track-start" / "track-end"; 
  -ms-align-self: center;
}
#upper-label { 
  -ms-grid-end: "end"; 
}

#lower-fill { 
  -ms-grid-column: "track-start" / "fill-split"; 
  -ms-align-self: end; 
  z-index: 5;
}
#upper-fill{ 
  -ms-grid-column: "fill-split" / "track-end"; 
  -ms-align-self: start; 
  z-index: 5; 
}

#thumb{ 
  -ms-grid-column: "thumb-start" / "thumb-end"; 
  z-index: 10;
}   

从代码上来说简单了很多,唯一可惜的是现在还不被任何浏览器支持,不过等浏览器支持的时候,大家可以尝试一下。

网格布局的概念和术语

前面的几个示例,大家肯定看得晕晕的,会这样的,但不用担心,那是因为我们刚接触一个新鲜事物,对其里面的内容并不了解。一旦了解了,一切都不是难事。接下来为大家介绍网格布局中最核心的部分,也是大家最想知道的部分。

在网格布局中,一个网格容器的内容排列是依靠于他里面网格的位置与对齐方式。网格是由水平和垂直网格比交织组成,他将网格容器的空间分为网格区域,网格项目将放置在这些网格区域中。在网格中有两套网格线:一套是沿着水平方向的轴定义列的网格张,另一套是沿着垂直方向的轴定义行。

CSS3 Grid Layout

上图演示的网格线包括了三条沿水平轴(block-axis)和四条沿垂直方向轴(inline-axis)。

1、网格轨道(Grid Tracks)

网格轨道是“grid column”或者“grid row”的另一种术语,换句话说,他就是两条相邻网格线之间的空间。每个网格轨道可以设置一个大小,用来控制宽度或高度或者行可能会增长。

在接下来的例中定义了一个三行两列的网格。第一列设置一个固定宽度“150px”,第二列设置是一个弹性尺寸,它是一个未赋值的网格空间,从而根据网格容器的变化而进行宽度的改变。如果网格容器的宽度是“200px”,那么第二列的宽度是“50px”。

#grid {
  display: grid;
  grid-definition-columns: 150px 1fr; /* 两列*/
  grid-definition-rows: 50px 1fr 50px /* 三行  */
}   

2、网格线(Grid Lines)

网格线是网格的水平和垂直的分界线。一个网格线存于行或列的两侧。他们可以参后数值指数,也可以由设计师指定名称。一个网格项目引用网格线来确定其网格中的位置属性。

下面两个例子创建了三个列网格线和四行网格线。第一个示例演示了设计师如何将一个使用网格行号的位置来确定网格项目的位置,第二个例子显式的设置了网格线。

/*具有三个列网格线和四个行网格线*/   
#grid {
  display: grid;
  grid-definition-columns: 150px 1fr; /*两列*/
  grid-definition-rows: 50px 1fr 50px;/*三行*/
}

#item1 { 
  grid-column: 2;
  grid-start: 1; 
  grid-end: 1; 
}   
/* 使用命名行,实现先前例子相等效果布局 */
#grid {
  display: grid;
  grid-definition-columns: 150px "item1-start" 1fr "item1-end";
  grid-definition-rows: "item1-start" 50px 1fr 50px "item1-end";
}

#item1 {
 grid-column: "item1-start" / "item1-end";
 grid-row: "item1-start" / "item1-end";
}   

3、网格区域(Grid Areas)

网格区域是一个逻辑空间,主要用来放置一个或多个网格项目。他有四条网格线,网格区域每边一条,四边相交组织的网格轨道可以调整网格区域大小。可以使用“grid-template”属性为网格容器显式的设置网格区域,或者隐式的使用网格线创建网格区域。网格项目可以使用“grid-placement”属性将其分配给一个网格区域。

#grid  {
  display: grid;
  grid-template: ". a"
                 "b a"
                 ". a";
  grid-definition-columns: 150px 1fr;
  grid-definition-rows: 50px 1fr 50px
}

#item1 { grid-area: a }
#item2 { grid-area: b }
#item3 { grid-area: b }

#item2 { align-self: head }
#item3 { justify-self: end; align-self: foot }   

4、网格容器(Grid Containers)

通过“display”属性给一个元素显式的设置了“grid”或者“inline-grid”属性值,这个元素将自动变成网格容器

一个网格容器将会创建一个新的网格格式化上下文内容(grid formatting context)。除是网格布局代替了块布局之外,网格格式化上下文和块格式化上下文是相同的。浮动对网格容器不会有影响,而且网格容器的margin不会和内容的margin相互层叠。

因为网格容器不是块容器,所以一些属性在网格布局中将会失效:

  • 多栏布局模块中的所有“column-*”属性运用在网格容器上将失效。
  • “float”和“clear”使用在网格项目上将失效
  • “vertical-align”使用在网格项目上将失效
  • “::first-line”和“::first-letter”这样的伪元素不能应用在网格容器上。

注意:如果一个元素指定了“display”值为“inline-grid”,并且此元素具有“float”或绝对定位时,这个元素将的“display”值将会以“grid”显示。

5、子网格容器(Subgrids)

有时候我们需要给网格项目设置为网格容器。那么我们可以使用“display:grid”,在这种情况之下,他是独立于网格布局的。而在某些情况下,要为内容设置多个网格,让网格项目相互一致,在这种情况之下,我们需要通过“dsplay”属性显式的设置为“subgrid”,让其显示为次网格。

例如,我们一个标签和输入框组成的列表表单:

<ul>
  <li><label>Name:</label> <input name=fn></li>
  <li><label>Address:</label> <input name=address></li>
  <li><label>Phone:</label> <input name=phone></li>
</ul>   

我们希望这个标签和输入文本框对齐,我们想给每个列表标签设置一个边框样式,这次就可以通过次网格布局实现

ul {
  display: grid;
  grid-auto-flow: rows;
  grid-definition-columns: auto 1fr;
}
li {
  display: subgrid;
  margin: 0.5em;
  border: solid;
  padding: 0.5em;
}
label {
  grid-column: 1;
}
input {
  grid-column: 2;
}   

6、网格项目(Grid Items)

在一个网格容器中包含了0个多个网格项目。网格容器的子元素称为网格项目以及运行在网格容器的文本将自动变成一个匿名的网格项目,然后如果只是一个空格,这个匿名项目就相当于“display:none”一相被隐藏在网格容器之中。

一个网格项目创建一个新的格式化上下文内容。这种格式化上下文内容类型取决于它的“display”值。

7、网格项目顺序(order)

网格项目顺序可以像flexobx模块一样,通过order属性来对网格项目进行顺序的重排。

定义网格

可以通过“grid-definition-rows”、“grid-definition-columns”和“grid-template”三个属性一起来定义网格容器的显示风格。

网格命名:grid-definition-rows和grid-definition-columns

这些属性指定的方式,可以使用空格分开track-list,用来指定网格的网线名称和网络轨道大小。每个大小都可以通过网格容器尺寸的百分比、固定的长度值,用来度量内容占的列或行,或者一小部分空闲的空间。它也可以使用“minmax()”函数结合前面提到的任何机制来定义一个min或max大小的列与行。

语法:

grid-definition-rows: none | <track-list> ;
grid-definition-columns: none | <track-list> ;   

默认值为“none”,主要适用于网格容器。

其中“grid-definition-rows”指定网格行的“track list”,而“grid-definition-columns”指定网格列的“track list”。

track list语法

<track-list> = [<string>*[<strack-size> | <repeat-function>]] + <string>*
<track-size> = minmax(<track-breadth> , <track-breadth>) | auto | <track-breadth>
<track-breadth> = <length> | <percentage> | <flex> | min-content | max-content   

属性参数:

  • <length>:CSS3所定义的长度值。
  • <percentage>:是一个逻辑大小,相对网格容器的宽度和高度。如果网格容器没有设置明确的值,那么将会视为“auto”值。
  • <flex>:一外非负值的维度,使用单“fr”。每个<flex>值可以按照他的值的比例使用网格容器剩余的空间,类似于flexbox中的flex。
  • max-content:网格项目占有网格轨道的最大内容宽度值
  • min-content:与max-content相反,网格项目占有网格轨道的最小内容宽度值
  • minmax(min,max):定义了一个尺寸范围,大于或等于最小值和小于或等于最大值。如果最大值小于最小时,最大值将会被忽略,“minmax(min,max)”被视为最小值
  • auto:minmax(min-content,max-content)的计算值。

来看一个“grid-definition-columns”的简单实例:

grid-definition-columns: 100px 1fr max-content minmax(min-content, 1fr);   

这个简单的示例中,我们创建了五个网格线:

  1. 网络容器开始边缘处
  2. 离网络容器开始边缘100px处
  3. 离前一条网格线,距离是自由空间的一半(自由空间宽度指网络容器宽度减去非弹性网格道宽度)
  4. 离前一条网格线,距离是两条线之间的最大宽度
  5. 最后一条网格线与前一条网络线间距离,大于或等于两条网格线的最小内容宽度,并且小于或等于自由空间宽度

除了上面那样定义之外,我们还可以这样定义,都将是有效的:

grid-definition-rows: 1fr minmax(min-content, 1fr);
grid-definition-rows: 10px repeat(2, 1fr auto minmax(30%, 1fr));
grid-definition-rows: calc(4em - 5px)   
1、命名网格线

网格线的命名除了可以通过数值定义之外,还可以使用“grid-definition-rows”和“grid-definition-columns”属性显式命名。还可以通过“grid-placement”属性命名一些有意义的网格线名,这样更容易后面的维护。

例如,下面的代码演示了一个有意义的网络线命名。注意,有些网格线有多个名称:

#grid {
  display: grid;
  grid-definition-columns: "first" "nav" 150px "main" 1fr "last";
  grid-definition-rows: "first" "header" 50px "main" 1fr "footer" 50px "last";
}  

CSS3 Grid Layout

2、重复行与列:repeat()

repeat()主要用来重复<track-list>这只是一个简写的语法,允许写大量的行与列,主要用来表现行与列的循环,让其更紧凑。repeat()语法如下所示:

<repeat-function> = repeat( <positive-integer> , [ <string>* <track-size> ]+ <string>* )   

第一个指定了重复的次数。第二个参数是track-list,是用来重复次数的内容。repeat()不能嵌套,不然声明不起作用。

下面的例子,展示了两种编写相同的网格定义。两个方法生成了一个单行四列的网格,每个列宽度是250px,列与列的间距是10px:

#grid {
  display: grid;
  grid-definition-columns: 10px "col-start" 250px "col-end" 
                           10px "col-start" 250px "col-end" 
                           10px "col-start" 250px "col-end" 
                           10px "col-start" 250px "col-end" 10px;
  grid-definition-rows: 1fr;
}

/* 相等效果的定义方式 */
#grid {
  display: grid;
  grid-definition-columns: repeat(4, 10px "col-start" 250px "col-end") 10px;
  grid-definition-rows: 1fr;
}  
3、弹性长度:fr

“fr”单位主要表示网格容器中额外空间。类似于flexbox中的flex。

网格区域命名:grid-template

这个属性主要用来定义网格区域的名称,并没有参与任何特定的网格项目,但可以使用“grid-placement”属性来控制网格项目位置。“grid-template”属性提供了一个可视化的网格结构,使用整体布局网格容器更易于理解与维护。

语法:

grid-template: none | <string>+    

默认值为“none”,主要适用于网格容器。

属性参数

  • none:网格容器没有定义网格区域的名称。
  • <string>+ :使用“grid-template”属性创建的字符串列表示一行(字符串与字符串之间空格分开),每个定义的字符串或者点号(.)字符编码为“U+002E”表示一列

在使用字符串列声明网格区域时,所有字符串列必须有相同数量的列,否则声明将无效。如果一个命名的网格区域横跨多个单元网格,但这些单元网格不是单独的矩形,那么这样的声明将无效。

来看一个简单的实例,使用“grid-template”属性为一个页面创建网格区域,他们包括的区域有页眉(head)、侧导航(nav)、页脚(foot)和主内容(main)。相用的,给四个网格区域定义名称,创建一个三行两列的网格。其中“head”在网格中的第一行,并占用两列:

#grid {
  display: grid;
  grid-template: "head head"
                 "nav  main"
                 "foot .   "
}
#grid > header { grid-area: head; }
#grid > nav    { grid-area: nav; }
#grid > main   { grid-area: main; }
#grid > footer { grid-area: foot; }   

自动生成行和列:grid-auto-rows和grid-auto-columns

如果一个网格项目放在了一行或列中,但没有使用“grid-definition-row”或“grid-definition-column”属性显式的设置其大小,那么他将隐式的方式创建一个网格轨道。这可以给行或列明确定位,或通过“auto-placement”创建额外的行或列。“grid-auto-columns”和“grid-auto-rows”属性就可以隐式的来指定其大小。

语法

grid-auto-columns:<track-minmax> 
grid-auto-rows:<track-minmax>

默认值为“auto”,其主要适用于网格容器。

我们来看一个简单的示例:网格项目B在网格线5处,它会自动创建四个隐式网格列。然而,只有两个(第一个和最后一个)运用到网格项目中,因为有两个网格轨道折叠为0的宽度。

CSS3 Grid Layout

上图显示的一个网格有一个隐含的行和四个隐式列,其中两个是大小为0。

<style type="text/css">
  #grid { 
    display: grid; 
    grid-definition-columns: 20px; 
    grid-definition-rows: 20px }
  #A { grid-column: 1; grid-row: 1; }
  #B { grid-column: 5; grid-row: 1 / span 2; }
  #C { grid-column: 1 / span 2; grid-row: 2; }
</style>

<div id="grid">
  <div id="A">A</div>
  <div id="B">B</div>
  <div id="C">C</div>
</div>

网格项目的放置

网格创建好之后,需要考虑的是网格项目的放置,接下来分别介绍网格项目放置的相关属性。

1、基于行的位置

网格项目在行上位置,可以通过“grid-before”, “grid-start”, “grid-after”和“grid-end”四个属性来控制。

grid-before: <grid-line>
grid-start:<grid-line> 
grid-after:<grid-line>
grid-end:<grid-line>   

“grid-before”, “grid-start”, “grid-after”和“grid-end”四个属性的默认值为“auto”,主要适用于网格项目。其中主要参数为“grid-line”,而grid-line语法如下:

<grid-line> = auto | [ <integer> || <string> ] | [ span && [ <integer> || <string> ] ] |  <ident>   

“grid-before”, “grid-start”, “grid-after”和“grid-end”四个属性分别指定网格区域中网格项目的前面、开始、后面、结束的网格线。在一个维度(行或列)就决定了一组网格线(指定的一个位置或者一个网格跨度),或者一个网格跨度(使用auto-placement隐式生成的维度)。其属性参数的具体含义如下:

  • <integer> || <string>:指定相应网格区域网格项目边缘是从显式网格边缘前面/开始的第几条网格线。如果他给定的是负值,那么他是反过来计算,将变成显式网格的后面或结束边。如果他给的值是 <string>只有网格线取了名才会被认为有效。如果<integer>省略,将会默认为“1”。如果其取值为“0”,将不会有任何效果。
  • span && [ <integer> || <string>:指定网格跨度:
  • <ident>:指定网格跨度,如果省略不写,默认为“auto”或者“span 1”。
  •  

例如,创建一个单行,8列的网格,并且命名网格线为1-9:

1  2  3  4  5  6  7  8  9
+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |
A  B  C  A  B  C  A  B  C
|  |  |  |  |  |  |  |  |
+--+--+--+--+--+--+--+--+   

下面通过索引标签值来定义网格项目两网格线之间的距离:

grid-start: 4; grid-end: auto;
/* Line 4 to line 5 */

grid-start: auto; grid-end: 6;
/* Line 5 to line 6 */

grid-start: 'C'; grid-end: 'C';
/* Line 3 to line 9 */

grid-start: 'C'; grid-end: span 'C';
/* Line 3 to line 6 */

grid-start: span 'C'; grid-end: 'C';
/* Line 6 to line 9 */

grid-start: span 'C'; grid-end: span 'C';
/* Error: both properties compute to ''auto'' */

grid-start: 5; grid-end: 'C';
/* Line 5 to line 9 */

grid-start: 5; grid-end: span 'C';
/* Line 5 to line 6 */

grid-start: 8; grid-end: 8;
/* Error: line 8 to line 9 */

grid-start: 'B' 2; grid-end: span 1;
/* Line 5 to line 6 */  

2、grid-column和grid-row

“grid-row”和“grid-column”属性是“grid-before/after”和“grid-start/end”的缩写。

3、自动布局:grid-auto-flow

网格项目自动放置在一个空闲的网格容器中。“grid-auto-flow”属性主要用控制行或列上是否有空闲的空间,用于添加所需容纳的内容。

grid-auto-flow: none | rows | columns   

其默认值为“none”,主要适用于网格容器。其属性参数:

  • none:网格区域中的网格项目自动设置它开始和前面的边缘在第一个网格线处,它的结束和末尾边缘设置根据数量的跨度来指定网格项目,默认为“1”。
  • rows:auto-placment根据网格项目填允,必要时反过来换行
  • columns:auto-placment根据网格项目填允,必要时反过来换列

auto-placement可以通过给网格项目设置“order”修改文档显示顺序。

例如下面的示例,网格有三列,每列的尺寸都是根据他们的内容尺寸决定。并且没有显式的标明行。设置“grid-auto-flow”的属性值为“rows”。网格将会根据三列进行搜索,根据结果添加新的一行,直到有足够的空间容纳所有网格项目。如下图所示:

CSS3 Grid Layout

<style type="text/css">
  form {
    display: grid;
    /* Define three columns, all content-sized,
       and name the corresponding lines. */
    grid-definition-columns: "labels" auto "controls" auto "oversized" auto;
    grid-auto-flow: rows;
  }
  form > label {
    /* Place all labels in the "labels" column and 
       automatically find the next available row. */
    grid-column: "labels";
    grid-row: auto;
  }
  form > input, form > select {
    /* Place all controls in the "controls" column and 
       automatically find the next available row. */
    grid-column: "controls";
    grid-row: auto;
  }

  #department {
    /* Auto place this item in the "oversized" column 
       in the first row where an area that spans three rows 
       won't overlap other explicitly placed items or areas 
       or any items automatically placed prior to this area. */
    grid-column: "oversized";
    grid-row: span 3;
  }

  /* Place all the buttons of the form 
     in the explicitly defined grid area. */
  #buttons {
    grid-row: auto;

    /* Ensure the button area spans the entire grid element 
       in the row axis. */
    grid-column: 1 / 1;
    text-align: end;
  }
</style>
<form>
  <label for="firstname">First name:</label>
  <input type="text" id="firstname" name="firstname" />
  <label for="lastname">Last name:</label>
  <input type="text" id="lastname" name="lastname" />
  <label for="address">Address:</label>
  <input type="text" id="address" name="address" />
  <label for="address2">Address 2:</label>
  <input type="text" id="address2" name="address2" />
  <label for="city">City:</label>
  <input type="text" id="city" name="city" />
  <label for="state">State:</label>
  <select type="text" id="state" name="state">
    <option value="WA">Washington</option>
  </select>
  <label for="zip">Zip:</label>
  <input type="text" id="zip" name="zip" />

  <div id="department">
    <label for="department">Department:</label>
    <select id="department" name="department" multiple>
      <option value="finance">Finance</option>
      <option value="humanresources">Human Resources</option>
      <option value="marketing">Marketing</option>
    </select>
  </div>

  <div id="buttons">
    <button id="cancel">Cancel</button>
    <button id="back">Back</button>
    <button id="next">Next</button>
  </div>
</form>   

Z轴的顺序

网格项目在交叉网格区域可以重叠放置,在非交叉的网格区域也可以使用负的margin值或定位重叠放置。当网格项目重叠时,可以通过“z-index”属性来控制网格项目在Z轴的顺序

正如下面的示例,效果图展示了几个重叠的网格项目,结合隐式的z-index和明确设置z-index的值用来控制他们的叠加顺序,如下图所示:

CSS3 Grid Layout

<style type="text/css">
  #grid { 
    display: grid; 
    grid-definition-columns: 1fr 1fr; 
    grid-definition-rows: 1fr 1fr 
  }
  #A { grid-column: 1 / span 2; grid-row: 2; align-self: foot }
  #B { grid-column: 1; grid-row: 1; z-index: 10 }
  #C { grid-column: 2; grid-row: 1; align-self: head; margin-left: -20px }
  #D { grid-column: 2; grid-row: 2; justify-self: end; align-self: head }
  #E { grid-column: 1 / span 2; grid-row: 1 / span 2;
       z-index: 5; justify-self: center; align-self: center; }
</style>

<div id="grid">
  <div id="A">A</div>
  <div id="B">B</div>
  <div id="C">C</div>
  <div id="D">D</div>
  <div id="E">E</div>
</div>   

浏览器兼容性

从上面的内容中可以了解到,CSS3 Grid Layout给布局带来的无限魅力,这将会让大家摆脱布局带来的恶梦。唯一可惜的是,到目前为止,支持Grid Layout布局模块的浏览器少得可怜。仅有IE10+支持,这回出乎您的意外了吧,没想到IE在这个领域先行了。不过就算是IE10+支持,也仅仅是支持部CSS3 Grid Layout模块中的部分属性值。

CSS3 Grid Layout

已被支持的属性

  1. display: grid | inline-grid
  2. grid-rows | grid-columns
  3. grid-row | grid-column
  4. grid-row-span | grid-column-span
  5. grid-row-align | grid-column-align

将要支持的属性

  1. grid-template
  2. grid-column-position
  3. grid-row-position
  4. grid-position
  5. grid-span
  6. grid-area
  7. grid-auto-columns
  8. grid-auto-rows
  9. grid-auto-flow

虽然现在还有很多浏览器不支持这个布局模块,虽然还不知道需要多久时间能将这个布局模块使用到案例中,虽然不知道将来这个布局模块会改变多少,但值得让我们庆幸的是,技术在不断向前更新,不断的在为广大的开发人员靠近。所以我们应该有着探索向前的精神,开始去接触他,并集大家的力量,一起完善他。只有这样我们才会不断的向前,不要因为不实用而放弃,不要因为兼容不好而放弃,不要....

请继续观注本站的相关更新,我们后续会继续介绍CSS3 Grid布局模块方面的教程与资料,我想你会喜欢的。

特别声明:本教程中的部分截图和所有示例代码来自于W3C官网

如需转载烦请注明出处:https://www.fedev.cn/css3/css3-grid-layout.html

NIke Dunk SB Low