乐趣区

关于css:CSS-Grid-网格布局教程

<!– 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 的成果。

留神,设为网格布局当前,容器子元素(我的项目)的 floatdisplay: inline-blockdisplay: table-cellvertical-aligncolumn-*等设置都将生效。

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 的缩写,意为 ” 片段 ”)。如果两列的宽度别离为 1fr2fr,就示意后者是前者的两倍。

.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-gapgrid-row-gap的合并简写模式,语法如下。

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

因而,下面一段 CSS 代码等同于上面的代码。

.container {grid-gap: 20px 20px;}

如果 grid-gap 省略了第二个值,浏览器认为第二个值等于第一个值。

依据最新规范,下面三个属性名的 grid- 前缀曾经删除,grid-column-gapgrid-row-gap 写成 column-gaprow-gapgrid-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 个单元格,而后将其定名为 ai的九个区域,别离对应这九个单元格。

多个单元格合并成一个区域的写法如下。

grid-template-areas: 'a a a'
                     'b b b'
                     'c c c';

下面代码将 9 个单元格分成 abc 三个区域。

上面是一个布局实例。

grid-template-areas: "header header header"
                     "main main sidebar"
                     "footer footer footer";

下面代码中,顶部是页眉区域 header,底部是页脚区域footer,两头局部则为mainsidebar

如果某些区域不须要利用,则应用 ” 点 ”(.)示意。

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属性除了设置成 rowcolumn,还能够设成 row densecolumn 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-columnsgrid-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-columnsgrid-template-rowsgrid-template-areas这三个属性的合并简写模式。

grid属性是 grid-template-rowsgrid-template-columnsgrid-template-areasgrid-auto-rowsgrid-auto-columnsgrid-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,因而会 ” 后行后列 ” 进行排列。读者能够把这个属性的值别离改成columnrow densecolumn 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-startgrid-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-startgrid-column-startgrid-row-endgrid-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 网格布局教程

退出移动版