共计 9858 个字符,预计需要花费 25 分钟才能阅读完成。
<!– more –>
一、概述
网格布局(Grid)是最弱小的 CSS 布局计划。
它将网页划分成一个个网格,能够任意组合不同的网格,做出各种各样的布局。以前,只能通过简单的 CSS 框架达到的成果,当初浏览器内置了。
上图这样的布局,就是 Grid 布局的拿手好戏。
Grid 布局与 Flex 布局有肯定的相似性,都能够指定容器外部多个我的项目的地位。然而,它们也存在重大区别。
Flex 布局是轴线布局,只能指定 ” 我的项目 ” 针对轴线的地位,能够看作是 一维布局 。Grid 布局则是将容器划分成 ” 行 ” 和 ” 列 ”,产生单元格,而后指定 ” 我的项目所在 ” 的单元格,能够看作是 二维布局。Grid 布局远比 Flex 布局弱小。
二、基本概念
学习 Grid 布局之前,须要理解一些基本概念。
2.1 容器和我的项目
采纳网格布局的区域,称为 ” 容器 ”(container)。容器外部采纳网格定位的子元素,称为 ” 我的项目 ”(item)。
<div> <div><p>1</p></div> <div><p>2</p></div> <div><p>3</p></div> </div>
下面代码中,最外层的 <div>
元素就是容器,内层的三个 <div>
元素就是我的项目。
留神:我的项目只能是容器的顶层子元素,不蕴含我的项目的子元素,比方下面代码的 <p>
元素就不是我的项目。Grid 布局只对我的项目失效。
2.2 行和列
容器外面的程度区域称为 ” 行 ”(row),垂直区域称为 ” 列 ”(column)。
上图中,程度的深色区域就是 ” 行 ”,垂直的深色区域就是 ” 列 ”。
2.3 单元格
行和列的穿插区域,称为 ” 单元格 ”(cell)。
失常状况下,n
行和 m
列会产生 n x m
个单元格。比方,3 行 3 列会产生 9 个单元格。
2.4 网格线
划分网格的线,称为 ” 网格线 ”(grid line)。程度网格线划分出行,垂直网格线划分出列。
失常状况下,n
行有 n + 1
根程度网格线,m
列有 m + 1
根垂直网格线,比方三行就有四根程度网格线。
上图是一个 4 x 4 的网格,共有 5 根程度网格线和 5 根垂直网格线。
三、容器属性
Grid 布局的属性分成两类。一类定义在容器下面,称为容器属性;另一类定义在我的项目下面,称为我的项目属性。这部分先介绍容器属性。
3.1 display 属性
display: grid
指定一个容器采纳网格布局。
div {display: grid;}
上图是 display: grid
的成果。
默认状况下,容器元素都是块级元素,但也能够设成行内元素。
div {display: inline-grid;}
下面代码指定 div
是一个行内元素,该元素外部采纳网格布局。
上图是 display: inline-grid
的成果。
留神,设为网格布局当前,容器子元素(我的项目)的
float
、display: inline-block
、display: table-cell
、vertical-align
和column-*
等设置都将生效。
3.2 grid-template-columns 属性,grid-template-rows 属性
容器指定了网格布局当前,接着就要划分行和列。grid-template-columns
属性定义每一列的列宽,grid-template-rows
属性定义每一行的行高。
.container { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; }
下面代码指定了一个三行三列的网格,列宽和行高都是100px
。
除了应用相对单位,也能够应用百分比。
.container { display: grid; grid-template-columns: 33.33% 33.33% 33.33%; grid-template-rows: 33.33% 33.33% 33.33%; }
(1)repeat()
有时候,反复写同样的值十分麻烦,尤其网格很多时。这时,能够应用 repeat()
函数,简化反复的值。下面的代码用 repeat()
改写如下。
.container { display: grid; grid-template-columns: repeat(3, 33.33%); grid-template-rows: repeat(3, 33.33%); }
repeat()
承受两个参数,第一个参数是反复的次数(上例是 3),第二个参数是所要反复的值。
repeat()
反复某种模式也是能够的。
grid-template-columns: repeat(2, 100px 20px 80px);
下面代码定义了 6 列,第一列和第四列的宽度为100px
,第二列和第五列为20px
,第三列和第六列为80px
。
(2)auto-fill 关键字
有时,单元格的大小是固定的,然而容器的大小不确定。如果心愿每一行(或每一列)包容尽可能多的单元格,这时能够应用 auto-fill
关键字示意主动填充。
.container { display: grid; grid-template-columns: repeat(auto-fill, 100px); }
下面代码示意每列宽度100px
,而后主动填充,直到容器不能搁置更多的列。
(3)fr 关键字
为了不便示意比例关系,网格布局提供了 fr
关键字(fraction 的缩写,意为 ” 片段 ”)。如果两列的宽度别离为 1fr
和2fr
,就示意后者是前者的两倍。
.container { display: grid; grid-template-columns: 1fr 1fr; }
下面代码示意两个雷同宽度的列。
fr
能够与相对长度的单位联合应用,这时会十分不便。
.container { display: grid; grid-template-columns: 150px 1fr 2fr; }
下面代码示意,第一列的宽度为 150 像素,第二列的宽度是第三列的一半。
(4)minmax()
minmax()
函数产生一个长度范畴,示意长度就在这个范畴之中。它承受两个参数,别离为最小值和最大值。
grid-template-columns: 1fr 1fr minmax(100px, 1fr);
下面代码中,minmax(100px, 1fr)
示意列宽不小于100px
,不大于1fr
。
(5)auto 关键字
auto
关键字示意由浏览器本人决定长度。
grid-template-columns: 100px auto 100px;
下面代码中,第二列的宽度,基本上等于该列单元格的最大宽度,除非单元格内容设置了min-width
,且这个值大于最大宽度。
(6)网格线的名称
grid-template-columns
属性和 grid-template-rows
属性外面,还能够应用方括号,指定每一根网格线的名字,不便当前的援用。
.container { display: grid; grid-template-columns: [c1] 100px [c2] 100px [c3] auto [c4]; grid-template-rows: [r1] 100px [r2] 100px [r3] auto [r4]; }
下面代码指定网格布局为 3 行 x 3 列,因而有 4 根垂直网格线和 4 根程度网格线。方括号外面顺次是这八根线的名字。
网格布局容许同一根线有多个名字,比方[fifth-line row-5]
。
(7)布局实例
grid-template-columns
属性对于网页布局十分有用。两栏式布局只须要一行代码。
.wrapper { display: grid; grid-template-columns: 70% 30%; }
下面代码将右边栏设为 70%,左边栏设为 30%。
传统的十二网格布局,写起来也很容易。
grid-template-columns: repeat(12, 1fr);
3.3 grid-row-gap 属性,grid-column-gap 属性,grid-gap 属性
grid-row-gap
属性设置行与行的距离(行间距),grid-column-gap
属性设置列与列的距离(列间距)。
.container { grid-row-gap: 20px; grid-column-gap: 20px; }
下面代码中,grid-row-gap
用于设置行间距,grid-column-gap
用于设置列间距。
grid-gap
属性是 grid-column-gap
和grid-row-gap
的合并简写模式,语法如下。
grid-gap: <grid-row-gap> <grid-column-gap>;
因而,下面一段 CSS 代码等同于上面的代码。
.container {grid-gap: 20px 20px;}
如果 grid-gap
省略了第二个值,浏览器认为第二个值等于第一个值。
依据最新规范,下面三个属性名的
grid-
前缀曾经删除,grid-column-gap
和grid-row-gap
写成column-gap
和row-gap
,grid-gap
写成gap
。
3.4 grid-template-areas 属性
网格布局容许指定 ” 区域 ”(area),一个区域由单个或多个单元格组成。grid-template-areas
属性用于定义区域。
.container { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; grid-template-areas: 'a b c' 'd e f' 'g h i'; }
下面代码先划分出 9 个单元格,而后将其定名为 a
到i
的九个区域,别离对应这九个单元格。
多个单元格合并成一个区域的写法如下。
grid-template-areas: 'a a a' 'b b b' 'c c c';
下面代码将 9 个单元格分成 a
、b
、c
三个区域。
上面是一个布局实例。
grid-template-areas: "header header header" "main main sidebar" "footer footer footer";
下面代码中,顶部是页眉区域 header
,底部是页脚区域footer
,两头局部则为main
和sidebar
。
如果某些区域不须要利用,则应用 ” 点 ”(.
)示意。
grid-template-areas: 'a . c' 'd . f' 'g . i';
下面代码中,两头一列为点,示意没有用到该单元格,或者该单元格不属于任何区域。
留神,区域的命名会影响到网格线。每个区域的起始网格线,会主动命名为
区域名 -start
,终止网格线主动命名为区域名 -end
。比方,区域名为
header
,则起始地位的程度网格线和垂直网格线叫做header-start
,终止地位的程度网格线和垂直网格线叫做header-end
。
3.5 grid-auto-flow 属性
划分网格当前,容器的子元素会依照程序,主动搁置在每一个网格。默认的搁置程序是 ” 后行后列 ”,即先填满第一行,再开始放入第二行,即下图数字的程序。
这个程序由 grid-auto-flow
属性决定,默认值是row
,即 ” 后行后列 ”。也能够将它设成column
,变成 ” 先列后行 ”。
grid-auto-flow: column;
下面代码设置了 column
当前,搁置程序就变成了下图。
grid-auto-flow
属性除了设置成 row
和column
,还能够设成 row dense
和column dense
。这两个值次要用于,某些我的项目指定地位当前,剩下的我的项目怎么主动搁置。
上面的例子让 1 号我的项目和 2 号我的项目各占据两个单元格,而后在默认的 grid-auto-flow: row
状况下,会产生上面这样的布局。
上图中,1 号我的项目前面的地位是空的,这是因为 3 号我的项目默认跟着 2 号我的项目,所以会排在 2 号我的项目前面。
当初批改设置,设为row dense
,示意 ” 后行后列 ”,并且尽可能严密填满,尽量不呈现空格。
grid-auto-flow: row dense;
下面代码的成果如下。
上图会先填满第一行,再填满第二行,所以 3 号我的项目就会紧跟在 1 号我的项目的前面。8 号我的项目和 9 号我的项目就会排到第四行。
如果将设置改为column dense
,示意 ” 先列后行 ”,并且尽量填满空格。
grid-auto-flow: column dense;
下面代码的成果如下。
上图会先填满第一列,再填满第 2 列,所以 3 号我的项目在第一列,4 号我的项目在第二列。8 号我的项目和 9 号我的项目被挤到了第四列。
3.6 justify-items 属性,align-items 属性,place-items 属性
justify-items
属性设置单元格内容的程度地位(左中右),align-items
属性设置单元格内容的垂直地位(上中下)。
.container { justify-items: start | end | center | stretch; align-items: start | end | center | stretch; }
这两个属性的写法完全相同,都能够取上面这些值。
- start:对齐单元格的起始边缘。
- end:对齐单元格的完结边缘。
- center:单元格外部居中。
- stretch:拉伸,占满单元格的整个宽度(默认值)。
.container {justify-items: start;}
下面代码示意,单元格的内容左对齐,成果如下图。
.container {align-items: start;}
下面代码示意,单元格的内容头部对齐,成果如下图。
place-items
属性是 align-items
属性和 justify-items
属性的合并简写模式。
place-items: <align-items> <justify-items>;
上面是一个例子。
place-items: start end;
如果省略第二个值,则浏览器认为与第一个值相等。
3.7 justify-content 属性,align-content 属性,place-content 属性
justify-content
属性是整个内容区域在容器外面的程度地位(左中右),align-content
属性是整个内容区域的垂直地位(上中下)。
.container { justify-content: start | end | center | stretch | space-around | space-between | space-evenly; align-content: start | end | center | stretch | space-around | space-between | space-evenly; }
这两个属性的写法完全相同,都能够取上面这些值。(上面的图都以 justify-content
属性为例,align-content
属性的图齐全一样,只是将程度方向改成垂直方向。)
- start – 对齐容器的起始边框。
- end – 对齐容器的完结边框。
- center – 容器外部居中。
- stretch – 我的项目大小没有指定时,拉伸占据整个网格容器。
- space-around – 每个我的项目两侧的距离相等。所以,我的项目之间的距离比我的项目与容器边框的距离大一倍。
- space-between – 我的项目与我的项目的距离相等,我的项目与容器边框之间没有距离。
- space-evenly – 我的项目与我的项目的距离相等,我的项目与容器边框之间也是同样长度的距离。
place-content
属性是 align-content
属性和 justify-content
属性的合并简写模式。
place-content: <align-content> <justify-content>
上面是一个例子。
place-content: space-around space-evenly;
如果省略第二个值,浏览器就会假设第二个值等于第一个值。
3.8 grid-auto-columns 属性,grid-auto-rows 属性
有时候,一些我的项目的指定地位,在现有网格的内部。比方网格只有 3 列,然而某一个我的项目指定在第 5 行。这时,浏览器会主动生成多余的网格,以便搁置我的项目。
grid-auto-columns
属性和 grid-auto-rows
属性用来设置,浏览器主动创立的多余网格的列宽和行高。它们的写法与 grid-template-columns
和grid-template-rows
完全相同。如果不指定这两个属性,浏览器齐全依据单元格内容的大小,决定新增网格的列宽和行高。
上面的例子外面,划分好的网格是 3 行 x 3 列,然而,8 号我的项目指定在第 4 行,9 号我的项目指定在第 5 行。
.container { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; grid-auto-rows: 50px; }
下面代码指定新增的行高对立为 50px(原始的行高为 100px)。
3.9 grid-template 属性,grid 属性
grid-template
属性是 grid-template-columns
、grid-template-rows
和grid-template-areas
这三个属性的合并简写模式。
grid
属性是 grid-template-rows
、grid-template-columns
、grid-template-areas
、grid-auto-rows
、grid-auto-columns
、grid-auto-flow
这六个属性的合并简写模式。
从易读易写的角度思考,还是倡议不要合并属性,所以这里就不具体介绍这两个属性了。
四、我的项目属性
上面这些属性定义在我的项目下面。
4.1 grid-column-start 属性,grid-column-end 属性,grid-row-start 属性,grid-row-end 属性
我的项目的地位是能够指定的,具体方法就是指定我的项目的四个边框,别离定位在哪根网格线。
grid-column-start
属性:左边框所在的垂直网格线grid-column-end
属性:左边框所在的垂直网格线grid-row-start
属性:上边框所在的程度网格线grid-row-end
属性:下边框所在的程度网格线.item-1 { grid-column-start: 2; grid-column-end: 4; }
下面代码指定,1 号我的项目的左边框是第二根垂直网格线,左边框是第四根垂直网格线。
上图中,只指定了 1 号我的项目的左右边框,没有指定高低边框,所以会采纳默认地位,即上边框是第一根程度网格线,下边框是第二根程度网格线。
除了 1 号我的项目以外,其余我的项目都没有指定地位,由浏览器主动布局,这时它们的地位由容器的 grid-auto-flow
属性决定,这个属性的默认值是 row
,因而会 ” 后行后列 ” 进行排列。读者能够把这个属性的值别离改成column
、row dense
和column dense
,看看其余我的项目的地位产生了怎么的变动。
上面的例子是指定四个边框地位的成果。
.item-1 { grid-column-start: 1; grid-column-end: 3; grid-row-start: 2; grid-row-end: 4; }
这四个属性的值,除了指定为第几个网格线,还能够指定为网格线的名字。
.item-1 { grid-column-start: header-start; grid-column-end: header-end; }
下面代码中,左边框和左边框的地位,都指定为网格线的名字。
这四个属性的值还能够应用 span
关键字,示意 ” 逾越 ”,即左右边框(高低边框)之间逾越多少个网格。
.item-1 {grid-column-start: span 2;}
下面代码示意,1 号我的项目的左边框间隔左边框逾越 2 个网格。
这与上面的代码成果齐全一样。
.item-1 {grid-column-end: span 2;}
应用这四个属性,如果产生了我的项目的重叠,则应用 z-index
属性指定我的项目的重叠程序。
4.2 grid-column 属性,grid-row 属性
grid-column
属性是 grid-column-start
和grid-column-end
的合并简写模式,grid-row
属性是 grid-row-start
属性和 grid-row-end
的合并简写模式。
.item { grid-column: <start-line> / <end-line>; grid-row: <start-line> / <end-line>; }
上面是一个例子。
.item-1 { grid-column: 1 / 3; grid-row: 1 / 2; } /* 等同于 */ .item-1 { grid-column-start: 1; grid-column-end: 3; grid-row-start: 1; grid-row-end: 2; }
下面代码中,我的项目 item-1
占据第一行,从第一根列线到第三根列线。
这两个属性之中,也能够应用 span
关键字,示意逾越多少个网格。
.item-1 { background: #b03532; grid-column: 1 / 3; grid-row: 1 / 3; } /* 等同于 */ .item-1 { background: #b03532; grid-column: 1 / span 2; grid-row: 1 / span 2; }
下面代码中,我的项目 item-1
占据的区域,包含第一行 + 第二行、第一列 + 第二列。
斜杠以及前面的局部能够省略,默认逾越一个网格。
.item-1 { grid-column: 1; grid-row: 1; }
下面代码中,我的项目 item-1
占据左上角第一个网格。
4.3 grid-area 属性
grid-area
属性指定我的项目放在哪一个区域。
.item-1 {grid-area: e;}
下面代码中,1 号我的项目位于 e
区域,成果如下图。
grid-area
属性还可用作 grid-row-start
、grid-column-start
、grid-row-end
、grid-column-end
的合并简写模式,间接指定我的项目的地位。
.item {grid-area: <row-start> / <column-start> / <row-end> / <column-end>;}
上面是一个例子。
.item-1 {grid-area: 1 / 1 / 3 / 3;}
4.4 justify-self 属性,align-self 属性,place-self 属性
justify-self
属性设置单元格内容的程度地位(左中右),跟 justify-items
属性的用法完全一致,但只作用于单个我的项目。
align-self
属性设置单元格内容的垂直地位(上中下),跟 align-items
属性的用法完全一致,也是只作用于单个我的项目。
.item { justify-self: start | end | center | stretch; align-self: start | end | center | stretch; }
这两个属性都能够取上面四个值。
- start:对齐单元格的起始边缘。
- end:对齐单元格的完结边缘。
- center:单元格外部居中。
- stretch:拉伸,占满单元格的整个宽度(默认值)。
上面是 justify-self: start
的例子。
.item-1 {justify-self: start;}
place-self
属性是 align-self
属性和 justify-self
属性的合并简写模式。
place-self: <align-self> <justify-self>;
上面是一个例子。
place-self: center center;
如果省略第二个值,place-self
属性会认为这两个值相等。
五、参考链接
- A Complete Guide to Grid, by Chris House
- Understanding the CSS Grid Layout Module, by Ian Yates
- How to Build an Off-Canvas Navigation With CSS Grid, Ian Yates
- Introduction to the CSS Grid Layout With Examples, Dogacan Bilgili
- Learn CSS Grid, Jonathan Suh
- How I stopped using Bootstrap’s layout thanks to CSS Grid, Cédric Kui
转载至 CSS Grid 网格布局教程