网格布局(Grid)是最强大的 CSS 布局方案,比flex还要强大。浏览器
它将网页划分红一个个网格,能够任意组合不一样大小的网格,作出各类各样的布局。
如上面的图,正是Grid布局的应用,还有好比 管理系统的主页 dashboard,正是应用了grid布局实现的。ide
Flex 布局是轴线布局,只能指定"项目"针对轴线的位置,能够看做是一维布局。Grid 布局则是将容器划分红"行"和"列",产生单元格,而后指定"项目所在"的单元格,能够看做是二维布局。函数
容器:采用网格布局的元素布局
项目:容器的直接子元素(和孙子元素无关)flex
行: 容器里面的水平区域spa
列: 容器里面的垂直区域3d
单元格:行和列的交叉区域code
网格线:水平网格线划分出行,垂直网格线划分出列。
正常状况下,n行有n + 1根水平网格线,m列有m + 1根垂直网格线,好比三行就有四根水平网格线。blog
Grid属性: 在grid布局中,有两类属性,一类是定义在容器上的,一类是定义在项目中的。it
给对应元素设置 display:grid或者 inline-grid
<div class="container"> <span class="item item-1">1</span> <span class="item item-2">2</span> <span class="item item-3">3</span> <span class="item item-4">4</span> <span class="item item-5">5</span> <span class="item item-6">6</span> </div>
.container { display: grid; }
默认状况下,子元素都是块级元素,而且默认只有一列(即grid-template-columns: 只有一个值;)
若是将其设置为display: inline-grid;则能够看到照样是一列,只是宽度没有100%平铺,而是实际宽度。
注意: 设为网格布局之后,容器项目的float、display:inline-block、display:table-cell、vertical-align和column-*等设置都将失效。
定义每一列的列宽。
.container { display: grid; grid-template-columns: 100px 100px 100px; }
有几个值,代表指定了几列,没定义列宽的列会自动跑到下一行,而多余的列会占用空间。
以下图:
表示采用父元素宽度的百分比定义当前列的宽度。
.container { display: grid; grid-template-columns: 33% 33%; }
表示重复,第一个参数为几回,后面参数表示每次的值是多少
.container { display: grid; grid-template-columns: repeat(3, 33.33%); }
repeat(3, 33.33%);等于 33.33% 33.33% 33.33%
好比,每列是固定的宽度,但是一行究竟放几列呢?不知道,只知道随着屏幕宽度大小,自动补充剩余空间。
fr表示比例关系
.container { display: grid; grid-template-columns: 1fr 2fr; //表示定义两列,这两列为1比2 }
上面grid-template-columns: 1fr 2fr;等同于 grid-template-columns: 33.33% 66.66%;
甚至能够这么写
grid-template-columns: 150px 1fr 2fr;
minmax()函数产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值。
.container { display: grid; grid-template-columns: 1fr 1fr minmax(200px, 1fr); }
表示由浏览器本身决定长度。
.container { display: grid; grid-template-columns: 50px auto auto auto; }
上面grid-template-columns: 50px auto auto auto;等同于
grid-template-columns: 50px 1fr 1fr 1fr;
定义每一行的行高,默认为子元素的行高
.container { display: grid; grid-template-rows: 100px 100px 100px; }
有几个值,代表指定了几行,没定义的行会采用默认的行高(不会自动跑到下一列),而多余的行,会占用空间
如图,只定义了前三行,后面三行均采用默认值。
默认先按grid-template-columns计算列数,而后自动计算行数。
当grid-template-columns和grid-template-rows组合是会出现,不匹配的状况。
好比一共6个项目,我定义了3列(
grid-template-columns),那么也就是自动2行,可是此时又指定了3行(grid-template-rows),那么此时就是3*3的网格。
而又有 一共6个项目,我定义了3列,那么自动就是2行,此时又指定1行,那么此时不会是31,仍是32.
其中grid-template-columns和grid-template-rows指定的网格,咱们能够称为标准网格,
而当实际的项目比定义的标准网格要多时。咱们称超出的部分,为扩展网格。
标准网格和扩展网格共同组成了Grid布局的网格。
后面咱们会经过另外的属性对于扩展网格定义宽高。
划分网格之后,容器的子元素会按照顺序,自动放置在每个网格。默认的放置顺序是"先行后列",即先填满第一行,再开始放入第二行,即下图数字的顺序。
grid-auto-flow默认值为row,即"先行后列"。若是为column,则先列后行。
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; grid-auto-flow: row; }
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; grid-auto-flow: column; }
grid-auto-flow不论是row仍是column,都是后面的列排不下了,那么会换行,此时,前一行后面就会有空白。
而若是设置成row dense和column dense,则前一行的空白会按顺序找出第一个能恰好放下的元素补齐。
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; grid-auto-flow: row; } .item-1{ grid-column-start: 1; grid-column-end: 3; } .item-2{ grid-column-start: 1; grid-column-end: 3; }
此时会看到右上方有个空白,由于item-3是紧跟在item-2后面的。
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; grid-auto-flow: row dense; } .item-1{ grid-column-start: 1; grid-column-end: 3; } .item-2{ grid-column-start: 1; grid-column-end: 3; }
而若是改为row dense,则会发现item-1和item-2没法拍到item-1后,换行了,接着按顺序找到了item-3补齐在item-1后面。
因此添加dense后,会“尽可能填满空格”
设置行与行的间隔(行间距)
.container { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; row-gap: 20px; }
设置列与列的间隔(列间距)
.container { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; row-gap: 20px; column-gap: 20px; }
row-gap和column-gap能够简写为
gap:<row-gap> <column-gap>
若是gap省略了第二个值,浏览器认为第二个值等于第一个值。
.container { display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; gap: 20px 20px; }
网格布局容许指定"区域"(area)编号,以便在项目中使用。
(对现有布局不会产生影响)
也能够进行合并,即起一样的名字
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; grid-template-areas: "header header header" "main main sidebar" "footer footer footer"; }
设置容器下全部单元格内容的水平位置(左中右),网格线不动,基于网格线的位置。它针对的是全部的单元格。
justify-items: start | end | center | stretch(默认);
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; justify-items: start; }
因为不是stretch后,项目的宽度都是自身的宽
设置容器下全部单元格内容的垂直位置(上中下),网格线不动,基于网格线的位置。它针对的是全部的单元格。
align-items: start | end | center | stretch(默认);
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; align-items: start; }
上面的justify-items和align-items能够合并成一个属性:place-items
place-items: <align-items> <justify-items>;
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; place-items: start start; }
整个内容区域在容器里面的水平位置(左中右),网格线会动,基于的是grid的边缘。
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
space-around和space-evenly区别在与,space-around指项目和项目之间的距离相等,可是离边缘是项目之间的一半,而space-evenly即便再边缘也等于项目之间的距离。
.container { display: grid; width: 600px; height: 400px; background-color: antiquewhite; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; justify-content: space-around; }
.container { display: grid; width: 600px; height: 400px; background-color: antiquewhite; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; justify-content: space-evenly; }
整个内容区域在容器里面的垂直位置(上中下),网格线会动,基于的是grid的边缘。
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
.container { display: grid; width: 600px; height: 400px; background-color: antiquewhite; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; align-content: space-around; }
.container { display: grid; width: 600px; height: 400px; background-color: antiquewhite; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; align-content: space-evenly; }
上面align-content和justify-content能够合并为 place-content。
place-content: <align-content> <justify-content>
.container { display: grid; width: 600px; height: 400px; background-color: antiquewhite; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; place-content: space-evenly space-around; }
用来设置,经过 grid-template-columns 和 grid-template-rows定义的标准网格大小,比实际的 项目数小时,多余的项目,即扩展网格的列和行的大小。
默认状况下多余的列和行,会使用项目中元素的实际内容的大小。
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px; }
定义了一个3列,1行的网格,一共能够放置3个项目,而下面是6个项目,也就意味后,item-4到item-6是在网格以外的。那么就使用自身元素的实际内容大小
<div class="container"> <span class="item item-1">1</span> <span class="item item-2">2</span> <span class="item item-3">3</span> <span class="item item-4">4</span> <span class="item item-5">5</span> <span class="item item-6">6</span> </div>
可是咱们能够经过grid-auto-rows来显示的指定,多余的部分的行高。它只影响多余的项目,对原本的网格项目不会形成影响。
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px; grid-auto-rows: 50px; }
用来设置,经过 grid-template-columns 和 grid-template-rows定义的网格大小,比实际的 项目数小时,多余的项目的列和行的大小。
默认状况下多余的列和行,会使用项目中元素的实际内容的大小。
可是和grid-auto-rows不一样的是,grid-auto-rows的多余行,会采用自身元素实际的行高,而grid-auto-columns的多余列,会填满剩余的空间(即便是span也是,奇怪)
.container { display: grid; grid-auto-flow: column; grid-template-columns: 100px; grid-template-rows: 100px 100px 100px; }
定义了一个1列,3行的,一供能够放置3个项目。那么第二列就是多余的列。
使用grid-auto-columns后。
.container { display: grid; grid-auto-flow: column; grid-template-columns: 100px; grid-template-rows: 100px 100px 100px; grid-auto-columns: 20px; }
前面的12个属性都是定义在容器上的,而下面的这些属性则是定义在容器里面的项目上的。
grid-column-start 定义项目垂直方向的 的起始网格(整数。好比grid-template-columns定义了3个值,那么grid-column-start能够取1到4)
grid-column-end 定义项目垂直方向的 的终止网格(整数。好比grid-template-columns定义了3个值,那么grid-column-start能够取1到4)
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; } .item-1{ grid-column-start: 1; grid-column-end: 3; }
item-1垂直方向从1开始,到3结束
grid-row-start 定义项目水平方向的 的起始网格(整数。好比grid-template-rows定义了3个值,那么grid-column-start能够取1到4)
grid-row-end 定义项目水平方向的 的终止网格(整数。好比grid-template-rows定义了3个值,那么grid-column-start能够取1到4)
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px 100px; } .item-1{ grid-column-start: 1; grid-column-end: 3; grid-row-start: 2; grid-row-end: 4; }
item-1垂直方向从1开始,到3结束, 水平方向从2开始,到4结束
上面的-start和-end能够改为网格线的名称。
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px; grid-template-areas: "header header setting" "main main sidebar" }
上面第一行定义了两列 header setting,因此他们的网格线分别为 header-start,header-end和setting-start,setting-end。其余也同样。
.item-1{ grid-column-start: header-start; grid-column-end: header-end; grid-row-start: main-start; grid-row-end: footer-end; }
指定项目放在哪个区域
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px; grid-template-areas: "header header setting" "main main sidebar" }
.item-1{ grid-area: header; }
其实咱们发现
grid-area: header;
和下面的效果如出一辙
grid-row-start: header; grid-column-start: header; grid-row-end: header; grid-column-end: header;
设置单元格内容的水平位置(左中右),跟justify-items属性的用法彻底一致,但只做用于单个项目。
justify-self: start | end | center | stretch;
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px; }
.item-1{ justify-self: center; }
设置单元格内容的垂直位置(上中下),跟align-items属性的用法彻底一致,但只做用于单个项目。
align-self: start | end | center | stretch;
.container { display: grid; grid-template-columns: 100px 168px 100px; grid-template-rows: 137px 100px; }
.item-1{ align-self: center; }
还可用 place-self属性place-self: <align-self> <justify-self>;