这是我参与第四届青训营笔记创作活动的第2天
前言
前几天老师在讲css布局提到grid,才突然回忆起以前做部落考核的一个特别适合用grid布局的部分,只不过当时我用的是flex。现在说起布局grid我相信重要程度比起flex不遑多让啊。除了兼容性方面,其余的方面都是很完美的。我相信随着技术的不断更替,兼容性已经不再是问题。那今天让我们来看看grid到底能够干啥吧。
什么是Grid?
大家应该已经了解Flex布局,而Grid 布局与 Flex 布局有一定的相似性,都可以指定容器内部多个项目的位置。但是,它们也存在重大区别。
Flex 布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局。Grid 布局则是将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,可以看作是二维布局。Grid 布局远比 Flex 布局强大。
了解Grid 布局是什么之后,我们还需要了解一些基本概念。
基本概念
容器和项目
我们将采用网格布局的区域,称为"容器"(container)。容器内部采用网格定位的子元素,称为"项目"(item)。
<div class="container">
<div class="item"><span>1</span></item>
<div class="item"><span>2</span></item>
</div>
上面代码中,最外层的<div>元素就是容器,内层的三个<div>元素就是项目。我特地将用类名将其形象化了。
不过有一点需要注意一下,项目只能是容器的顶层子元素,不包含项目的子元素,比如上面代码的
<span>元素就不是项目。Grid 布局只对项目生效。
行和列
容器里面的水平区域称为"行"(row),垂直区域称为"列"(column)。
单元格
行和列的交叉区域,称为"单元格"(cell)。
正常情况下,n行和m列会产生n x m个单元格。比如,3行4列会产生12个单元格。
网格线
划分网格的线,称为"网格线"(grid line)。水平网格线划分出行,垂直网格线划分出列。
正常情况下,n行有n + 1根水平网格线,m列有m + 1根垂直网格线,比如三行就有四根水平网格线。
上图是一个 4 x 4 的网格,共有5根水平网格线和5根垂直网格线。
一般而言,是从左到右,从上到下,1,2,3 进行编号排序,从右到左,从下到上,则是按照 -1,-2,-3…顺序进行编号排序。
好了,基本概念介绍的差不多了,接下来进入容器属性。
容器属性
grid-template-*
容器指定了网格布局以后,接着就要划分行和列。grid-template-columns属性定义每一列的列宽,grid-template-rows属性定义每一行的行高。
grid-template-rows:100px 100px 100px 100px (表示四行)
如上文所示,想写多少行或多少列,就填写相应属性的个数。
我们可以看到,上面代码后面的数值都相同,那有没有什么办法能不写那么多重复的东西呢?答案是可以的!
1、这里就不得不提到repeat()。
repeat()的第一个参数是重复的次数,第二个是重复的值。那么上面的代码可以写为:
grid-template-columns:repeat(4,100px)
还有一个问题是,如果我们不填写,那会是什么结果呢?答案是自动分配,将容器自动充满。
2、 这就依赖于auto-fill 。有时,单元格的大小是固定的,但是容器的大小不确定,auto-fill属性就会自动填充 。还是用上边的例子,我们可以这么写:
grid-template-columns:repeat(auto-fill,100px)
3、我们还能用fr方便表示比例关系 (fraction的缩写,片段的意思)
grid-template-columns:repeat(4,1fr)//宽度平均分为四列等分
4、如果我们想控制极值,那就可以用到minmax() ,它将产生一个长度范围,2个参数,一个最小值,一个最大值
grid-template-columns:1fr minmax(150px,1fr)
最小都不会小于150px
5、如果是三列布局且中间一列想自适应,那就可以用auto 表示由浏览器自己决定长度
grid-template-columns:100px auto 100px (不写则默认auto)
达到中间自动填充,根据浏览器的大小自动计算的效果。
6、网格线(作用:帮助定位 格子定位到哪跟线上,使用方括号,指定每一根网格线的名字,方便以后的引用)
grid-template-columns:[c1] 100px [c2] 100px [c3] // 2列3根网格线
row-gap / columns-gap
可以设置item 之间的距离,他们还可以缩写,用gap
column-gap:20px (列与列之间的距离)
row-gap:20px (行与行之间的距离)
gap:20px 20px(合并简写,若省略了第二个值,则与第一个同值)
grid-template-areas
一个区域由单个或多个单元格组成 需要在项目属性里面设置,自己想怎么划分就怎么划分 一个格子可以成为一个区域 两个格子也可以成为一个区域
grid-auto-flow
划分网格以后,容器的子元素会按照顺序,自动放置在每一个网格。默认的放置顺序是"先行后列",即先填满第一行,再开始放入第二行,即下图数字的顺序。这个顺序由grid-auto-flow属性决定,默认值是row,即"先行后列"。也可以将它设成column,变成"先列后行"。
grid-auto-flow:column; //先列后行
grid-auto-flow:column dense;//(用dense可以提高空间的利用率)
对齐方式
取值可以是:start | end | center | stretch
-
设置整个内容区域的水平垂直对齐方式
justify-content: center; align-content: center; -
设置所有单元格内容的水平垂直对齐方式
justify-item: center; align-item: center;
grid-auto-columns / grid-auto-rows
有时候,一些项目的指定位置,在现有网格的外部。比如我只设置了3×2个项目,但是实际有7个,此时就可以用这个属性来设置多出来的项目。
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px;
grid-auto-rows: 50px; //指定是50px
}
如果不指定这两个属性,浏览器完全根据单元格内容的大小,决定新增网格的列宽和行高。
项目属性
指定具体位置
比如要定位图中单元格1,我们可以这么写,有一点类似于用坐标确定矩形的意思[(1,1)(2,2)]
grid-column-start:1;
grid-column-end:2;
grid-row-start:1;
grid-row-end:2;
grid-area
grid-area 指定项目在哪一个区域 (结合容器属性一起使用),比如图中的1所在项目
grid-template-areas:'a a a'
'b b b'
'c c c'
grid-area:b;
可简写为: grid-area:1/1/3/3;
justify-self / align-self
只能用于单个项目(单元格)的水平/垂直方向
justify-self:center;
align-self:center;
简写:place-self:center center
到此,记忆性的东西就告一段落了,接着就是应用了,感兴趣的伙伴不如还原一下以下的图,没错,就是以前我用flex写的那个。
实战
图来源于央视网
始终觉得,实践是最好的复习方式。最后的最后,谢谢大家这么厉害还来看我,如果发现问题或者需要补充的点麻烦大家通过评论告诉我。博取众长,共同进步!