内容简介:在上篇——需要注意得是,Grid布局与我们之前所熟悉的css布局思路有很大的不同,阅读这篇文章之前,需要把我们平时对css的刻板印象抛弃掉,准备接受知识的洗礼吧,少年!与 Flex 相同,Grid 也分为容器与元素两个概念;在一个 html 标签中添加样式:
前言
在上篇—— JavaScript五十问——对比来说CSS的Grid与FlexBox(上篇) ,我介绍了Flex的属性与使用,今天我们来总结一下Grid的具体使用方法,最后会结合Flex与Grid布局讲一讲二者的联系与不同。
需要注意得是,Grid布局与我们之前所熟悉的css布局思路有很大的不同,阅读这篇文章之前,需要把我们平时对css的刻板印象抛弃掉,准备接受知识的洗礼吧,少年!
Grid
与 Flex 相同,Grid 也分为容器与元素两个概念;在一个 html 标签中添加样式: display:grid 或者 display:inline-grid ,即构建了一个 Grid 的容器,里面的 dom 元素即为 Grid 元素。同样,Grid 也分为两类属性,分别装载在容器与元素上,下面一一说明。
HTML结构说明
以下所有例子均基于或扩展于下面的HTML结构:
<style>
.container{
width:500px;
background-color:#999;
}
.item{
width: 50px;
background-color:#567;
color:#fff;
}
</style>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</div>
Grid 基本概念介绍
网格
Grid容器里面有网格一系列的概念;听着唬人,但是结合图很容易理解。
网格线
水平方向有垂直方向的线段即为 网格线
网格轨道
两个相邻的平行网格线之间的区域就是 网格轨道
网格单元
四个相邻边组成的区域就是网格单元。
fr
fr 是Grid中特有表示 尺寸 的单位,是 分数——fraction 的缩写,假设我们现在有四个grid元素,每个元素的宽度都是1fr,那么每个元素的实际宽度就是总宽度的1/4。
fr也可以跟%,px 共同使用,他的计算规则就是刨去px与%的剩余空间作为fr分配空间,所有fr相加之和作为分母,分子为每个元素对应的fr的值。(当然,在Grid语境下,我们是不需要设置width属性的,这样说是为了让大家容易理解)。
这样说来好像fr仅仅是%的另外一种写法,随着我的介绍,你就会发现fr优于%的地方。
接下来,我还是以脑图为思路介绍Grid的各个属性。
容器属性
grid-template
grid-tempalte是三个属性的简写,这三个属性都是描述整块区域即多个 网格单元 的属性。
grid-template-rows
grid-template-rows是描述 横向 的 单元轨道属性 的。可以试想一下,我们在一个Grid容器中,关于这个属性,我们关心的是什么呢?无非就是这个容器中有多少行,每行的高度;所以,这个属性就是让我们定义这些值得。先来看语法:
grid-template-rows: <track-size> | <line-name> <track-size> ...;
这个属性除了可以定义轨道尺寸和个数之外,还允许我们定义两个轨道之间的网格线的名称,至于他的作用,我们先按下不表,先来看这个属性是怎样定义每个轨道的尺寸和轨道个数的。
先来看一个例子:
.container{
grid-template-rows:200px auto 1fr 1fr 20%;
grid-row-gap:10px;//定义轨道之间的间距
}
grid-template-rows定义了五个值,表示Grid容器里面有五行,可以使用任意的定义尺寸的方式,效果如下
其中 auto 值就表示元素的实际占用大小。
Grid分配空间首先计算除了fr对应轨道的尺寸,然后将剩余尺寸按照比例分配给fr加持的元素。
以上,我们在Grid容器里定义了五行容器轨道,当我们定义轨道过多时,可以使用repeat函数来减少我们的工作量,语法为:
grid-template-rows:repeat(n, size)
例子:
.container{
grid-template-rows:repeat(5,1fr);
grid-row-gap:10px;
}
上面就定义了五个网格轨道,每个轨道的高度是Grid容器高度的1/5。
grid-template-columns
grid-template-columns 与 grid-template-rows使用方法是一致的,这两个属性共同作用于Grid容器,相当于把Grid容器分割为m*n个子区域。
例子:
.container{
grid-template-rows:repeat(3,1fr);
grid-template-columns: repeat(2, 1fr)
上面这个例子就会得到六个均等分的子区域。
通过上面两个属性,相信大家对Grid布局有一个基本的认识了,想必对Grid二维布局的模式也有一些概念了,接下来才是Grid精彩之处,震撼灵魂的地方!
grid-template-areas
上面两个属性分别设置Grid行属性和列属性,grid-template-areas是设置Grid区域的。所谓区域是由一个或多个行、列、单元组成的一篇区域。首先看一下语法:
.container {
grid-template-areas:
"<grid-area-name> | . | none | ..."
"...";
}
其中
grid-area-name 表示网格区域的名称
. 表示空的网格区域
none 表示没有定义网格区域
在我们平时开发时,经常会出现上头下尾中间两栏布局的情况,下面我们使用grid-template-areas完成这样的布局。
<style>
.container{
display:grid;
grid-template-rows:60px auto 60px;
grid-template-columns:100px 1fr;
grid-template-areas:
"header header"
"left right"
"footer footer";
}
.container .item:first-child{
grid-area: header;
}
.container .item:nth-child(2){
grid-area: left;
}
.container .item:nth-child(3){
grid-area: right;
}
.container .item:nth-child(4){
grid-area: footer;
}
</style>
.container{
display:grid;
grid-template-rows:60px 1fr 60px;
grid-template-columns:100px 1fr;
grid-template-areas:
"header header"
"left right"
"footer footer";
}
.container .item:first-child{
grid-area: header;
}
.container .item:nth-child(2){
grid-area: left;
}
.container .item:nth-child(3){
grid-area: right;
}
.container .item:nth-child(4){
grid-area: footer;
}
.container{
display:grid;
grid-template-rows:60px 1fr 60px;
grid-template-columns:100px 1fr;
grid-template-areas:
"header header"
"left right"
"footer footer";
}
.container .item:first-child{
grid-area: header;
}
.container .item:nth-child(2){
grid-area: left;
}
.container .item:nth-child(3){
grid-area: right;
}
.container .item:nth-child(4){
grid-area: footer;
}
</style>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
在Grid容器中,我们定义了6个网格单元,使用 grid-tempalte-areas 划分了header footer left right 四片区域;而在 grid元素 中,每个元素使用 grid-area 来指定元素所对应的grid区域。因此,我们虽然划分了6个单元,但可以使用四个元素来表示。
是不是很神奇呢,更神奇的是,grid-area-name是支持中文定义的。
以上grid-template的子属性就说完了,grid-template是以上那三个属性的简写方式,语法如下:
grid-tempalte:<'grid-template-rows'> / <'grid-template-columns'>`
`grid-tempalte:[ <line-names>? <string> <track-size>? <line-names>? ]+
[ / <explicit-track-list> ]?
例如上面的例子可以这样简写
grid-template:
"header header" 60px
"left right" 1fr
"footer footer" 60px
/ 50px 1fr;
grid-gap
grid-gap用来描述Grid 区域之间间隙的尺寸大小。语法如下:
.container {
grid-gap: <grid-row-gap> <grid-column-gap>;
}
grid-gap是简写属性,也可以分别定义grid行间隔和grid 列间隔。
.container{
grid-row-gap:10px;
grid-column-gap:10px;
}
grid-gap与margin与padding不同,它不占用当前元素的盒模型的位置。
上图显示的很清楚,3号元素的margin 与 padding 均为零。
place-items
place-items 是 justify-items 和 align-items 的简写方式
这两个属性分别定义了 Grid元素 水平与垂直分布方式。
语法如下:
justify-items: stretch | start | end | center;
align-items: stretch | start | end | center;
对于这四个属性,默认stretch,相信读者在熟悉了Flex布局后都不会陌生,这里不多做解释,直接看例子,以align-items 为例:
.container{
display:grid;
grid-template:
"header header" 160px
"footer footer" 160px
/ 160px 160px;
height:500px;
grid-row-gap:10px;
grid-column-gap: 10px;
}
首先定义四个grid单元,每个单元的长宽均为160px
接下来我们更改align-items的值
align-items:stretch
align-items:center
align-items:start
align-items: end
为了方便大家理解,我用红框框出每个Grid单元所占用的空间。由此可以看出,place-items属性是用来表明一个元素在当前grid单元中的分布方式,这个元素的拉伸,居中等都是以grid单元作为参考的。
place-content
place-content同样是一个简写属性,它包括:justify-content 和 align-content,它表示grid元素在grid容器中的分布方式,只有当grid容器中有剩余空间的时候才起作用。
语法如下:
justify-content: stretch | start | end | center | space-between | space-around | space-evenly; align-content: stretch | start | end | center | space-between | space-around | space-evenly;
属性值得含义同Flex;这里不再过多说明,读者可以自行验证。
grid-auto-rows 与 grid-auto-columns
grid-auto-rows 和 grid-auto-columns;用于当实际的Grid的元素多余划分的Grid元素时,定义多余Grid元素的长宽;
例如我们在HTML里面一定了五个Grid元素,但是在css中只定义了2*2的Grid单元,可以使用grid-auto来定义多出来的轨道的尺寸。
grid-auto-flow
grid-auto-flow的用法需要结合下面的元素属性来说明。
元素属性
grid-column-start grid-column-end
两个属性是用来定义Grid元素列方向上的起始与终止位置。
语法格式为:
grid-column-start: <number> | <name> | span <number> | span <name> | auto
其中:
number为起止第几条网格线
name 为网格线的名称
span <number>网格元素会跨越网格单元的数量
span <name> 当前的网格元素会在哪一个网格线上开始or终止
注意 使用span 如果是start,表示这个从开始的位置跨过的grid单元,如果是end 表示这个元素覆盖的grid单元。
grid-column是它们的简写方式,语法为:
grid-column:grid-column-start / grid-column-end
grid-row-start grid-row-end
grid-row属性与grid-column用法一致,这里不过多赘言,直接看例子:
.container{
display:grid;
grid-template-rows:[rone]1fr[rtwo]3fr[rthree]1fr[rfour];
grid-template-columns: [cone]1fr[ctwo]5fr[cthree]2fr[cfour];
height:500px;
}
.item:first-child{
grid-column-start:1;
grid-column-end:cfour;
grid-row-start:rone;
grid-row-end: 2;
}
.item:nth-child(2){
grid-column-start:1;
grid-column-end:span 1;
grid-row-start:rtwo;
grid-row-end: span cthree;
}
.item:nth-child(3){
grid-column-start: ctwo;
grid-column-end:4;
grid-row-start:rtwo;
grid-row-end: span cthree;
}
.item:nth-child(4){
grid-column-start:1;
grid-column-end:4;
grid-row-start:3;
grid-row-end: span 4;
}
效果:
首先在Grid容器中划分出9个grid单元,这九个单元被六个网格线所分割,并给这六个网格线命名。在四个Grid元素中定义横行的起始位置。
grid-row 与 grid-column结合使用,可以起到与Grid-template-areas同样的效果。
grid-area
grid-area我们在前面已经接触过一部分了,他与Grid容器中的grid-template-areas一起定义,也是grid-column与grid-row的简写属性,语法为:
grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;
name为grid区域的名称,与grid-tempalte-areas结合使用。
上面我们的例子就可以用grid-area表示:
.item:first-child{
grid-area:1/rone/2/cfour;
}
place-self
justify-self
justify-self定义Grid元素的水平布局方式的,例如,我们在Grid容器中定义justify-items的属性为默认属性,而在某一个Grid元素中定义justify-self为center,那么其他元素表现为拉伸,这个元素则单独表现为居中。也就是说,justify-self在Grid容器中对应的属性是justify-items。
语法为:
.item {
justify-self: stretch | start | end | center;
}
algin-self
align-self与justify-self一致,改变的是这个元素的垂直部署方式,与容器中align-items对应,
语法为:
.container {
align-self: stretch | start | end | center;
}
由于这四个属性值已经在我们的系列文章中出现多次,这里不再多说。
plac-self是以上两个属性的简写方式,语法为:
.container {
place-items: <align-self> / <justify-self>;
}
再论fr
Grid的所有属性已经介绍完毕了,在对Grid宇宙有了一个基本的认识后,我们再回头看一下Grid宇宙中出现的新尺寸单位——fr。
可能大家在刚刚结仇到fr这个单位时,都会认为它是%的一个别名;但是,我们来看最下面的例子:
我们在Grid容器中划分出四个Grid区域,并定义每个区域的宽度为25%,并定义每个Grid元素之间的gap宽70px;
.container{
display:grid;
grid-template-columns: repeat(4, 25%);
grid-column-gap: 70px;
}
效果如下:
很明显,这里元素溢出了。这种情况是我们不想看到的。
下面,我们将25%替换为1fr看一下效果:
效果对比很明显。
而造成两者显著区别的原因是二者的计算空间方式的不同。使用百分比它的分母是父元素的width或者height,而fr的分母是父元素中剩余空间的尺寸;css会首先计算使用%和px定义的元素尺寸,剩下的空间再由fr元素进行比例分配。这就是使用fr不会出现元素溢出的情况。当然我们也可以使用calc避免溢出的尴尬,但是两种解决方案孰优孰略已经一目了然了。
Flex 与 Grid
Flex布局与Grid布局有很多相似的地方,例如justify-content和justify-items的用法。但是更多的是不同,最重要的是Grid开拓了 二维 布局的方式,相比于传统的css布局方式(Flex、bootstrp 12列),Grid开创了网格的概念,用户可以从 横纵 两个方面部署元素。正是因为如此,在Grid宇宙中,传统的css布局、尺寸属性就显得格格不入了。而Grid布局的二维特性所带来的整体观,使Grid在 页面级别 样式上更加游刃有余。而Flex相比于Grid 更加适合小组件上的样式开发,二者并不冲突相信在Grid 与 Flex双双加持之下,一定会收获更好的开发效果!
Grid布局还是一个较新潮的概念,我也是一般看资料学习,一边分享,由于缺少实际的开发经验,对于很多属性的应用场景还没有很深入的理解,故而有的属性一笔带过;如果我有理解不正确的地方,欢迎大家指正!
参考文献
以上所述就是小编给大家介绍的《JavaScript五十问——对比来说CSS的Grid与FlexBox(下篇)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 威胁情报相关标准简介 (下篇)
- 【前端面试分享】- 寒冬求职下篇
- 【MyBatis源码分析】Configuration加载(下篇)
- 【MyBatis源码分析】Configuration加载(下篇)
- Golang经典笔试题及答案(下篇)
- 系统架构系列(四):业务架构实战下篇
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Building Social Web Applications
Gavin Bell / O'Reilly Media / 2009-10-1 / USD 34.99
Building a social web application that attracts and retains regular visitors, and gets them to interact, isn't easy to do. This book walks you through the tough questions you'll face if you're to crea......一起来看看 《Building Social Web Applications》 这本书的介绍吧!