1.概览
css display中有个属性值是grid,说起来惭愧的是,在长达近2年的开发实操中我极少用到这个属性。在整理响应式布局的我才重新将其拾起。
grid可以说是在我看来css最强大的布局方案之一了,总体而言,他将网页划分为一个个区域,并且可以对这个区域进行任意组合,以达到布局的效果。(之前这些功能都是一些css框架封装好的,现在css也支持了)
grid和flex有一定的相似性(我在之前的开发过程中flex的应用率极高。。),但flex更像是一种线性的布局,根据横轴和纵轴的各种配置来达到布局的效果。而grid则是一种二维布局,他利用row(行)和column(列)来分割出不同的二维区域,通过对这些二维区域中的一切(是的,几乎是能想到的一切)进行操作来实现不同的布局。
flex布局 grid布局从两张图中可以看出,grid更适用于一些多行多列,宽高不等的复杂布局,从布局的功能上来说,grid远比flex强大的多。
2.基本概念
归纳一下grid的布局一些基本概念,一方面是自身对知识进行梳理,一方面也方便文档的通读性。
2.1 容器(Container)
这也是css布局的传 统 艺 能了,简单的描述来说他就是应用display:grid
的元素,同时他也应该是所有项目(item)的直接父元素。
html代码:
<div class="container">
<div class="item1"></div>
<div class="item2"></div>
<div class="item3"><p>No<p></div>
</div>
复制代码
css代码:
.container{
display:grid
}
复制代码
这里的最外层的div
就是整个grid布局的容器
2.2 项目(item)
项目同学们也应该同样熟悉,沿用2.1中的代码,例如item1,item2,item3都是容器(container)的直接子元素,所以他们都是从属于container的项目(item)。
但是要注意的被包裹在item3的<p>No</p>
并不是项目(item),他并不是容器(container)的直接子元素
2.3 线(Line)
从线开始往下的概念我会用图片的方式来直观的展示,而如何实现我相信看完属性的详解之后你就自然能够了然于胸了
线图中交错的线就是line(包括了最外层的虚线),所以若是一个容器(container)有4列(column),意味着他有5条列方向的线(line)
2.4 路径(Track)
路径是指相邻两条线(line)包裹的区域
如图中的 蓝色track部分就是由col4线(line)和col5线(line)分割出来的路径(track)2.5 单元格(Cell)
单元格(cell)指分别由两条相邻的行线和两条相邻的列线分割出来的区域(area)
如图中的cell单元格就是由col3,col4,row2,row3分割出来的一个区域(area),只不过这个区域(area)比较特殊,他是一个单元格(cell)2.6 区域(Area)
区域(area)是指由两条任意不同的行线和两条任意不同列线分割的区域,它是由若干个单元格(cell)组成的
如图中的 红色main区域就是一个由col1,col3和row2,row4分割的区域(area)2.7 fr
fr单元允许你用等分网格容器剩余可用空间来设置 网格轨道(Grid Track) 的大小。
剩余可用空间是除去所有非灵活网格项之后计算得到的。
复制代码
在这个例子中,可用空间总量减去 100px 后,再给 fr 单元的值 按1:2:1 等分:
grid-template-columns: [row-one] 1fr [row-two] 2fr [row-three]1fr [row-four] 100px [row-five] ;
复制代码
3.属性
3.1 容器(container)属性
- display
- grid-template-columns
- grid-template-rows
- grid-template-areas
- grid-template
- grid-column-gap
- grid-row-gap
- grid-gap
- justify-items
- align-items
- place-items
- justify-content
- align-content
- place-content
- grid-auto-columns
- grid-auto-rows
- grid-auto-flow
- grid
display
取值: display: grid | inline-grid
grid就不加赘述了,inline-grid的其实就是把这个容器元素变成一个内联元素
grid-template-columns / grid-template-rows
取值:
<track-size>
: 可以是长度值,百分比,或者等份网格容器中可用空间(使用 fr 单位)<line-name>
:给你的线(line)任意的起个名字
html代码:
<body>
<div class="container">
<div class="item1 center"></div>
<div class="item2 center"></div>
<div class="item3 center"></div>
<div class="item4 center"></div>
<div class="item5 center"></div>
</div>
</body>
复制代码
css代码:
.container {
display: grid;
grid-template-columns: [row-one] 100px [row-two] 100px [row-three]100px [row-four] 100px [row-five] ;
grid-template-rows: 100px 100px auto 100px;
}
.center{
display: flex;
justify-content: center;
align-items: center;
}
复制代码
你可以明确指定网格线的名称,就像代码中对grid-template-columns
中所做一样。 你也会发现容器中对项目的排序默认是按行进行,从左往右,从上往下。如图中所示的那样,但这就出现了一个问题,本该在第二行第一个的item5去哪了呢?
答案就是grid-template-rows: 100px 100px auto 100px;
中这个auto的锅了,属性值为auto的情况下,它会默认设置为子元素所需的高度,但是item5中并没有子元素,于是row2就“消失”了。
尝试着给item5添加一个text
...
<div class="item5 center">text</div>
...
复制代码
如图,item5在row2中出现了
grid-template-areas
grid-area属性可以指定一个网格区域(Grid Area) 名称来定义网格模板。
重复网格区域的名称导致内容跨越这些单元格。一个点号(.)代表一个空单元格。这个语法本身可视作网格的可视化结构。
值:
<grid-area-name>
:由网格项的 grid-area 指定的网格区域名称- .(点号) :代表一个空的网格单元
- none:不定义网格区域
直接上代码:
grid-template-areas:
"none header header sidebar"
"main main simpleCell sidebar"
"main main footer .";
.item1 {
grid-area: header;
background-color: orange;
}
.item2 {
grid-area: main;
background-color: red;
}
.item3 {
grid-area: sidebar;
background-color: blue;
color: white;
font-size: 30px;
}
.item4 {
grid-area: footer;
background: green;
}
.item5 {
grid-area: simpleCell;
background: #694545;
}
复制代码
通俗一点。grid-template-areas
中写一个命名方阵,然后item(项目)中用grid-area
属性使用其中的命名来进行对应。
tips:在grid-template-areas
中的命名分布必须是一个矩形
grid-column-gap/grid-row-gap
指定网格线(line)的大小。相当于设置行和列的间距
话不多说上代码
grid-column-gap:50px;
grid-row-gap:25px;
复制代码
行列的距离被分开了!需要注意的是如果你的区域(area)包含多个单元格(cell),区域的width将会把线(line)的宽度计算在内!
justify-items
justify-items可以在行轴上设置item们在各自area中的对齐方式
可取的值:
- start:将网格项对齐到其单元格的左侧起始边缘(左侧对齐)
- end:将网格项对齐到其单元格的右侧结束边缘(右侧对齐)
- center:将网格项对齐到其单元格的水平中间位置(水平居中对齐)
- stretch:填满单元格的宽度(默认值)
直接上代码体验一下:
justify-items: start;
复制代码
justify-items: center;
复制代码
justify-items: end;
复制代码
需要注意的点是,header,main和siderbar其实是占据的是一个由多个cell组成的area,所以他的位置会取area的起始,中间,和尾部
align-items
justify-items可以在列轴上设置item们在各自area中的对齐方式
可取的值:
- start:将网格项对齐到其单元格的顶部起始边缘(顶部对齐)
- end:将网格项对齐到其单元格的底部结束边缘(底部对齐)
- center:将网格项对齐到其单元格的垂直中间位置(垂直居中对齐)
- stretch:填满单元格的高度(默认值)
这个的实际效果可以参考justify-items
,可以自行尝试。
place-items
place-items是align-items和justify-items的合并写法
可取的值:
<align-items> <justify-items>
第一个值设置给align-items,第二个值设置给justify-items,如果只设置第一个值那么这个值将同时赋予 align-items和justify-items
justify-content
有时候,你的item们加起来的宽度都没有container的大,同时item们使用的都是px等固定宽度的长度单位,那么这时候就可能需要justify-content出马来调整item们来到达你想要的位置了。
可取的值:
- start:将网格对齐到 网格容器(grid container) 的左侧起始边缘(左侧对齐)
- end:将网格对齐到 网格容器 的右侧结束边缘(右侧对齐)
- center:将网格对齐到 网格容器 的水平中间位置(水平居中对齐)
- stretch:调整 网格项(grid items) 的宽度,允许该网格填充满整个 网格容器 的宽度
- space-around:在每个网格项之间放置一个均匀的空间,左右两端放置一半的空间
- space-between:在每个网格项之间放置一个均匀的空间,左右两端没有空间
- space-evenly:在每个网格项目之间放置一个均匀的空间,左右两端放置一个均匀的空间
依次放图:
justify-content: start justify-content: center justify-content: end justify-content: space-around; justify-content: space-between; justify-content: space-evenly;align-content
justify-content的列轴版。赋值什么的都一模一样的,建议自己尝试一哈
place-content
place-content是align-content和justify-content的合并写法
可取的值:
<align-content> <justify-content>
第一个值设置给align-content,第二个值设置给justify-content,如果只设置第一个值那么这个值将同时赋予 align-content和justify-content
grid-auto-columns / grid-auto-rows
指定自动生成的track的高度/宽度,当container中item多于cell的数量,或者item的定位在当前所有的cell之外时候,container就会自动创建(隐式轨道),来以此填补缺少的位置。
可取的值:
<track-size>
:可以是长度值,百分比,或者等份网格容器中可用空间的分数(使用 fr 单位)
上代码:
.container {
width: 100%;
display: grid;
grid-template-columns: 100px 100px 100px 100px ;
grid-template-rows: 100px 100px 100px 100px;
grid-auto-columns:70px;
grid-auto-rows: 70px;
border: 1px solid black;
grid-template-areas:
"none header header sidebar"
"main main simpleCell sidebar"
"main main footer .";
}
...
.item6 {
width: 100%;
grid-column: 6;
grid-row: 5;
background: #694545;
}
复制代码
可以看到,这个container初始是由一个4*4的row和column组成的,但是在item6中使用了grid-column/grid-row将其指定在5行6列的位置,那么此刻,container就会创建隐式轨道(图中的虚线部分)。grid-auto-columns和grid-auto-rows就是分别用来指定隐式轨道的列宽和行高。
grid-auto-flow
如果你有一些item,并且他们没有被指定放置的位置,那么这个时候container会按照一定规则去排列他们,grid-auto-flow可以设置这个规则。
可取的值:
- row:依次填充每行,根据需要添加新行 (默认)
- column:依次填入每列,根据需要添加新列
- dense:在稍后出现较小的网格项时,尝试填充网格中较早的空缺
上代码:
通用部分——
.item1 {
width: 100%;
grid-column: 1 / span 3;
// grid-area: header;
background-color: orange;
}
.item2 {
// grid-area: main;
width: 100%;
grid-column: 1 / span 2;
background-color: red;
}
.item3 {
width: 110px;
// grid-area: sidebar;
background-color: blue;
color: white;
font-size: 30px;
}
.item4 {
width: 100px;
// grid-area: footer;
background: green;
}
.item5 {
width: 100px;
// grid-area: simpleCell;
background: #694545;
}
.item6 {
width: 100%;
background: #694545;
}
复制代码
grid-auto-flow: row;
grid-auto-flow: column;
grid-auto-flow: row dense;
grid-auto-flow: column dense;
.item1 {
width: 100%;
grid-row: 1 / span 3;
// grid-area: header;
background-color: orange;
}
.item2 {
// grid-area: main;
width: 100%;
grid-row: 1 / span 2;
background-color: red;
}
复制代码
项目(item)属性
Tips: float,display: inline-block,display: table-cell,vertical-align 和 column-* 属性对item无效
grid-column-start / grid-column-end / grid-row-start / grid-row-end与 grid-column / grid-row
通过引用特定线(lines) 来确定item在网格内的位置。
grid-column-start / grid-row-start 是网格项开始的网格线。
grid-column-end / grid-row-end 是网格项结束的网格线。
在使用时要注意的是 如果使用了以上这些子属性来进行布局,请不要同时使用grid-area来配合container中的grid-template-areas。前者会被后者的布局效果所覆盖
上代码
.container {
grid-template-columns: [col-1]100px [col-2] 100px [col-3]100px [col-4] 100px [col-5];
grid-template-rows: [row-1]100px [row-2]100px [row-3]100px [row-4]100px[row-5];
grid-auto-columns:70px;
grid-auto-rows: 70px;
...
.item1 {
grid-column-start: 1;
grid-column-end: span col-4;
grid-row-start: 2;
grid-row-end: span 2;
width: 100%;
// grid-area: header;
background-color: orange;
z-index: 100;
}
}
复制代码
以上代码中我们对每一条line进行了命名,以方便我们进行布局
item1 即是 图中的heaher部分。可以看到,从列来说,他从1也就是最左侧的col-1开始,一直到col4结束。从行来说,他从由上至下的2也就是row-2开始,跨域了2条线。
span X代表着从该线开始的第X根线结束,你也可以用线的名称直接来指定位置,比如row-1,col-2,前提是你得命名。
grid-column / grid-row
是上述4个属性的简写方法。
上述属性同样可以写成
grid-column: 1 / span col-4;
grid-row: 2 / span 2;
复制代码
grid-area
可取的值:
<name>
:在container中指定的名称<row-start> / <column-start> / <row-end> / <column-end>
:数字或线名称
其实前面一直在用...已经非常眼熟了。并不推荐<row-start> / <column-start> / <row-end> / <column-end>
的写法,可读性很差。远不如指定<name>
justify-self
container属性justify-items的item单项目版,取值和效果完全一致
align-self
container属性align-items的item单项目版,取值和效果完全一致
place-self
justify-self
和 align-self
的合并简写
可取的值:
- auto 默认
<align-self> <justify-self>
,如果只写一个,它同时将被赋值给第二个
来源:oschina
链接:https://my.oschina.net/u/4407552/blog/4273403