首页 专题 H5案例 前端导航 UI框架

CSS:Grid布局

作者:TG 日期: 2017-02-03 字数: 25845 阅读: 9159
CSS Grid布局,是一个基于网格的二维布局系统,目的是用来优化用户界面设计。

不过,目前任何浏览器默认是不支持Grid布局的,但幸运的是,我们可以设置Chrome、Opera或者Firefox的特殊标志来启用它。在Chrome或Opera中,在地址栏中输入chrome://flags(opera://flags),然后将experimental web platform features 选项设置为enable;在Firefox中,将layout.css.grid.enabled选项设置为可用。


注意!注意!重磅消息,在2017年3月左右,大部分浏览器都会开始默认支持Grid布局,所以,现在完全有必要开始学习Grid布局。

网上关于Grid布局的资料已经很多了,本文只是用来记录一下Grid布局的相关属性和用法,防止别人的网站在某一天挂掉。

1、启用网格容器

我们使用display属性来定义一个网格容器,它的grid值决定了容器展现为块级还是内联形式。一旦启用网格容器,它的所有子元素都进入grid文档流,称为网格子项。

display: grid | inline-grid | subgrid

  • grid:定义一个块级的网格容器
  • inline-grid:定义一个内联的网格容器
  • subgrid:定义一个继承其父级网格容器的行和列的大小的网格容器,它是其父级网格容器的一个子项。

注意:column, float, clear和vertical-align对网格容器没有效果。

简单术语介绍:

每一块表示一个网格子项(网格单元),4个(任意数量)网格子项组成了网格区域。

2、网格容器的属性

2.1 grid-template-columns/grid-template-rows

词法:

grid-template-columns: <track-size> ... | <line-name> <track-size> ...;

grid-template-rows: <track-size> ... | <line-name> <track-size> ...;

  • <track-size>:定义网格单元的宽高,其单位可以是一个长度(如px、em、rem、vw、vh)或百分比,也可以是网格中自由空间的份数(单位为fr)。
  • <line-name>:定义网格线的名称,它不是必须值。可以一个你选择的任意名字,当没有显示设定时,它的名字以数字表示。

实例:
当你在轨迹值中间留空格,网格线将被自动以数字命名:

.container{   

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

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

}


当然,我们还可以给网格线指定一个名字:

.container{   

  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-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];  

}

如果你定义了容器的重复部分,你可以使用repeat()方法来生成多个相同值:

.container{   

  grid-template-columns: repeat(3, 20px [col-start]) 5%;  

}


/* 等价于 */

.container{   

  grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start] 5%;  

}


特殊单元:fr

fr单元允许你将网格容器中的自由空间设置为一个份数:

.container{   

  grid-template-columns: 1fr 1fr 1fr;  

}

在上面的代码中,将网格容器的每个子项设置为三分之一。

注意:自由空间是在固定子项确定后开始计算的

.container{   

  grid-template-columns: 1fr 50px 1fr 1fr;  

}

在上面的代码中,自由空间是fr单位的总和但不包括50px。

2.2 grid-template-areas

grid-template-areas可以配合grid-area定义一个显式的网格区域。grid-template-areas定义网格区域,然后使用grid-area调用声明好的网格区域名称来放置对应的网格项目。

词法:

grid-template-areas: "<grid-area-name> | . | none | ..." "..." 

  • <grid-area-name>:在grid-area中指定的网格区域名字
  • .:一个句点表示一个空的网格单元
  • none:没有网格区域被定义

实例:

<div class="container">   

  <div class="item-a"></div>   

  <div class="item-b"></div>   

  <div class="item-c"></div>   

  <div class="item-d"></div>   

</div>

设置CSS样式:

.item-a{   

  grid-area: header;  

}  

.item-b{   

  grid-area: main; 

}  

.item-c{   

  grid-area: sidebar; 

}  

.item-d{   

  grid-area: footer; 

}  

.container{    

  width: 300px;

  height:200px;   

  display:grid;   

  grid-template-columns: 1fr 1fr 1fr 1fr;   

  grid-template-rows: auto;   

  grid-template-areas: "header header header header"   

                       "main main . sidebar"   

                       "header footer header footer";  

}

在上面的代码中,我们将创建一个4乘以3的网格容器,第一行由header区域组成,中间一行由 2 个main区域和1个空单元和1个sidebar区域组成,最后一行由footer区域组成。


2.3 grid-column-gap/grid-row-gap/grid-gap

指定网格线的大小,也可以说是网格子项之间的间距。

词法:

grid-column-gap: <line-size>

grid-row-gap: <line-size>

  • <line-size>:长度值

grid-gapgrid-column-gapgrid-row-gap的简称:

grid-gap: <grid-column-gap> <grid-row-gap>

如果只有一个值,grid-row-gap的值将和grid-column-gap一样。

实例:

.container{   

  display:grid;   

  grid-template-columns: 100px 50px 100px;   

  grid-template-rows: 80px auto 80px;    

  grid-column-gap: 10px;   

  grid-row-gap: 15px;  

}

注意:间隔仅仅作用在网格子项之间,不作用在容器边缘。



2.4 justify-items/align-items

justify-items

让网格子项的内容和列轴对齐(align-items则相反,是和行轴对齐),这个值对容器里面的所有网格子项都有用。

justify-items: start | end | center | stretch

  • start:内容和网格区域的左边对齐
  • end:内容和网格区域的右边对齐
  • center:内容和网格区域的中间对齐
  • stretch:填充整个网格区域的宽度(默认值)

align-items

让网格子项的内容和行轴对齐,这个值对容器里面的所有网格子项都有用。

align-items: start | end | center | stretch;

  • start:内容和网格区域的顶部对齐
  • end:内容和网格区域的底部对齐
  • center:内容和网格区域的中间对齐
  • stretch:填充整个网格区域的高度(默认值)


2.5 justify-content/align-content

justify-content

如果用像px非弹性单位定义的话,总网格区域大小有可能小于网格容器,这时候你可以设置网格的对齐方式(垂直于列网格线对齐)。

justify-content: start | end | center | stretch | space-around | space-between | space-evenly ;

  • start:左对齐
  • end:右对齐
  • center:居中对齐
  • stretch:填充网格容器
  • space-around:在每个网格子项中间放置均等的空间,在始末两端只有一半大小
  • space-between:两边对齐,在每个网格子项中间放置均等的空间,在始末两端没有空间
  • space-evenly:网格间隔相等,包括始末两端


align-content

如果用像px非弹性单位定义的话,总网格区域大小有可能小于网格容器,这时候你可以设置网格的对齐方式(垂直于行网格线对齐)。

align-content: start | end | center | stretch | space-around | space-between | space-evenly 

  • start:顶部对齐
  • end:底部对齐
  • center:居中对齐
  • stretch:填充网格容器
  • space-around:在每个网格子项中间放置均等的空间,在始末两端只有一半大小
  • space-between:上下对齐,在每个网格子项中间放置均等的空间,在始末两端没有空间
  • space-evenly:在每个网格子项中间放置均等的空间,包括始末两端



2.6 grid-auto-columns/grid-auto-rows

自动生成隐式网格轨道(列和行),当你定位网格项超出网格容器范围时,将自动创建隐式网格轨道。

grid-auto-columns: <track-size>

grid-auto-rows: <track-size>

  • <track-size>:可以是一个长度,百分比或者是一个网格中自由空间的份数(通过使用fr单位)

为了说明隐式网格轨迹如何被创建,思考一下这个:

.container{   

  grid-template-columns: 60px 60px;   

  grid-template-rows: 90px 90px  

}

在上面的代码中,我们创建了 2 x 2 的网格。

但现在想象你使用grid-column和grid-row来定位你的网格子项,就像这样:

.item-a{   

  grid-column: 1 / 2;   

  grid-row: 2 / 3;  

}  

.item-b{   

  grid-column: 5 / 6;   

  grid-row: 2 / 3;  

}



我们告诉.item-b在第 5 列网格线开始第 6 列网格线结束,但我们还没有定义第 5 或者第 6 列。因为我们引用的线不存在,0 宽度的隐式网格轨迹将被创建来填充这些空缺。我们可以使用grid-auto-columnsgrid-auto-rows来指定这些隐式网格轨迹的宽度:

.container{   

  grid-auto-columns: 60px;  

}



2.7 grid-auto-flow

在没有设置网格项的位置时,这个属性控制网格项怎样排列。

grid-auto-flow: row | column | row dense | column dense

  • row:按照行依次从左到右排列
  • column:按照列依次从上到下排列
  • dense:按先后顺序排列

来看看下面的例子:

<section class="container">   

  <div class="item-a">item-a</div>   

  <div class="item-b">item-b</div>   

  <div class="item-c">item-c</div>   

  <div class="item-d">item-d</div>   

  <div class="item-e">item-e</div>  

</section>

下面定义5列2行网格,同时定义grid-auto-flow:row

.container{   

  display: grid;   

  grid-template-columns: 60px 60px 60px 60px 60px;   

  grid-template-rows: 30px 30px;   

  grid-auto-flow: row;  

}

再设置网格子项布局:

.item-a{   

  grid-column: 1;   

  grid-row: 1 / 3;  

}  

.item-e{   

  grid-column: 5;   

  grid-row: 1 / 3;

} 

由于我们设置了grid-auto-flow:row,item-b、item-c和item-d在行上是从左到右排列,如下:


如果我们设置 grid-auto-flow: column,结果如下:


2.8 grid

grid是一种简写形式:

grid: none | <grid-template-rows> / <grid-template-columns> | <grid-auto-flow> [<grid-auto-rows> [ / <grid-auto-columns>] ];


3、网格子项的属性

3.1 grid-column-start/grid-column-end/grid-row-start/grid-row-end/grid-column/grid-row


通过网格线来定义网格项的位置。grid-column-startgrid-row-start定义网格项的开始位置,grid-column-endgrid-row-end定义网格项的结束位置。

grid-column-start: <number> | <name> | span <number> | span <name> | auto ; 

grid-column-end: <number> | <name> | span <number> | span <name> | auto ;

grid-row-start: <number> | <name> | span <number> | span <name> | auto ; 

grid-row-end: <number> | <name> | span <number> | span <name> | auto ;

  • <number> | <name>:可以是一个数字以适用被标记了数字号的网格线,或者是一个名字以适用命名了的网格线
  • span <number>:子项将跨越指定数字的网格轨迹
  • span <name>:子项将跨越指定名字之前的网格线
  • auto:自动布局,自动跨越或者默认跨越一个。


实例:

.item-a{   

  grid-column-start: 2;   

  grid-column-end: five;   

  grid-row-start: row1-start   

  grid-row-end: 3  

}



.item-b{   

  grid-column-start: 1;   

  grid-column-end: span col4-start;   

  grid-row-start: 2   

  grid-row-end: span 2  

}



grid-columngrid-column-startgrid-column-end的简称;grid-rowgrid-row-startgrid-row-end的简称。

grid-column: <start-line> / <end-line> | <start-line> / span <value>;   

grid-row: <start-line> / <end-line> | <start-line> / span <value>;

实例:

.item-c{   

  grid-column: 3 / span 2;   

  grid-row: third-line / 4;  

}



3.2 grid-area


给网格子项取一个名字以让它被由grid-template-areas属性创建的模板引用。同时,这个属性还可以用来更简短地表示grid-row-start+ grid-column-start + grid-row-end+ grid-column-end

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

  • <name>:选择的名字
  • <row-start> / <column-start> / <row-end> / <column-end> – 可以是网格线的数字或名字


实例:

作为分配一个名字给网格子项的一种方式:

.item{  

.item-d{   

  grid-area: header  

}

作为grid-row-start+ grid-column-start + grid-row-end+ grid-column-end的一种简写:

.item-d{   

  grid-area: 1 / col4-start / last-line / 6  

}



3.3 justify-self/align-self


(1)justify-self


让网格子项的内容以列轴对齐(与之相反align-self是跟行轴对齐),这个值可以应用在单个网格子项的内容中。

justify-self: start | end | center | stretch

  • start – 让内容在网格区域左对齐
  • end – 让内容在网格区域右对齐
  • center – 让内容在网格区域中间对齐
  • stretch – 填充着呢个网络区域的宽度(默认值)




(2)align-self


让网格子项的内容以行轴对齐(与之相反justify-self是跟列轴对齐),这个值可以应用在单个网格子项的内容中。

align-self: start | end | center | stretch

  • start – 让内容在网格区域上对齐
  • end – 让内容在网格区域下对齐
  • center – 让内容在网格区域中间对齐
  • stretch – 填充着呢个网络区域的高度(默认值)




参数文章:

Grid 的完整介绍

A Complete Guide to Grid

Grid入门


如有错误,欢迎指正!


目录