Grid网格布局

原创
2023-12-16
0
html,css,Grid,布局
Grid布局很强,有点类似于html中的table标签,最大的不同之处在于grid是写css,table是写html标签(当然还有很多区别这里就不作说明了)。它们都是将网页分为一个个网格,利用这些网格组合做出各种布局。
Grid与Flex也有一定相似性,都可以指定内部成员的位置。不同之处在于,Flex布局是轴线布局,一列或一行,可以看作是一维布局。Grid布局是多行多列,可以看作是二维布局。
虽然但是,这个学起来要比Flex复杂一些,有点难度,一般的网页布局基本Flex就能搞定,Grid更适合复杂的布局方式。
我的观点是能用Flex+css实现的就用Flex,如果其中需要js计算才能实现的,就用Grid。所以在我看来Grid的适用场景比Flex少的多,因为大部分场景Flex就能实现。

行列属性 grid-template-rows,grid-template-columns

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
grid-template-rows: 50px 50px 50px 50px; 
grid-template-columns: 50px 50px 50px 50px 50px;
grid-template-rows
grid-template-columns
4行5列 5行4列 7行3列 4行6列
grid-template-rows是行高,有多少行就定义多少个
grid-template-columns是列宽,有多少列就定义多少个
如果有n多行列这样定义是不是很麻烦,当然有简便方法,repeat()函数

行列重复简化函数 repeat()

那如果我们不指定行列,让它自己根据设定的列宽度去塞满容器呢,这就用到了auto-fill关键字

自动填充关键字 auto-fill

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
.grid{ 
  width: 250px;
  height: 250px;
  display: grid;
  {mark}grid-template-columns: repeat(auto-fill,30px); 
  padding: 5px; 
  background: #efefef;
}
.grid div{ 
  background:#ccc; 
  margin: 1px;
}
{mark}.grid div:nth-child(2){ height: 50px;}
{mark}.grid div:nth-child(14){ height: 100px;}
上面只设定列宽30px,自动塞满整个容器,但是由于容器是250px,容器剩余空间放不下一个单元格的时候自动换行,所以容器最右侧有10px的空间,同时我们指定了第2、14个单元格的高,这样行高就不是平均分布了,而是根据单元格的高度来自适应。
这时候如果有大聪明说我只设定行高会怎样?这个就留待你自己试一试了。
上面的示例中取值用的px,当然你也可以用%,也可以用比例单位fr

置多余网格的行高列宽 grid-auto-columns grid-auto-rows

1
2
3
4
5
6
7
8
设置2行2列单元格宽高都是100像素,其他的单元格自动分配高度
grid-template-rows: repeat(2,100px);
grid-template-columns: repeat(2,100px);
自动分配高度的单元格行高设置100px
grid-template-columns: repeat(2,100px);
{mark}grid-auto-rows:100px
我们设置2行2列的网格1234行高列宽都是100px,5678的行高并不是100px而是自动分配高度,我们也想让5678的行高也是100px,那就要设置grid-auto-rows:100px,columns也同理

比例单位 fr

fr是grid的长度单位的比例,这样说有点抽象,还是看实例吧
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
将行列单位换成fr
grid-template-rows: 1fr 2fr 3fr 4fr;
grid-template-columns: 4fr 3fr 2fr 1fr;
单位能混用
grid-template-rows: 1fr 2fr 3fr 4fr;
grid-template-columns: 30px 50% 1fr 2fr;
点击代码可查看效果
我们定义了行高比1:2:3:4,列宽比4:3:2:1,不管容器是多大,行列都是这个比例。
grid-template-columns: 30px 50% 1fr 2fr; 译为:
第一列宽为 30像素
第二列宽为 容器总宽度的50%
第三列宽为 容器总宽度 - 所有不是fr列宽 的三分之一
第四列宽为 容器总宽度 - 所有不是fr列宽 的三分之二
如果我们想设定某一列的最小宽度和最大宽度,某一行的最小高度和最大高度呢,这就用到了minmax()函数

范围函数 minmax()

minmax(最小,最大) 比较简单,没啥可说的,看示例吧
1
2
3
4
5
6
grid-template-columns: 1fr 1fr minmax(50px,2fr);
grid-template-columns: 1fr minmax(50px,2fr) 1fr;

自动填充剩余空间关键字 auto

由容器剩余空间决定,示例如下:
1
2
3
4
5
6
width: 250px;
grid-template-rows: 1fr 1fr; 
{mark}grid-template-columns: 30px auto 30px

行列间距 grid-row-gap、grid-column-gap、grid-gap

grid-row-gap 行间距、grid-column-gap 列间距。 前面两者的简写grid-gap:行间距 列间距
1
2
3
4
5
6
width: 250px;
{mark}grid-gap:2px
grid-template-rows: 1fr 1fr; 
grid-template-columns: 30px auto 30px
还没学到grid-gap之前的示例中我们用 .grid div{margin: 1px;} 来设置单元格的间距
现在用grid-gap:2px(等同于grid-gap:2px 2px)就可以直接在容器上设置行列间距

区域布局 grid-template-areas,grid-area

grid-template-areas 用于定义区域,一个区域由一个或者多个单元格组成
grid-area 指定单元格放在哪个区域,先看代码及示例
1
2
3
4
5
6
1
2
3
4
5
6
注意这几行
.grid{
  grid-template-areas:"g4 g4 g1 g5 ."
                      "g3 g2 g1 g6 g6";
}
.grid .g1{grid-area: g1;}
……
.grid .g6{grid-area: g6;}
grid-template-areas定义了2行5列的容器,
第一行为 g4 g4 g1 g5 .
第二行为 g3 g2 g1 g6 g6
g1-g6为单元格中定义的grid-area,注意这个.为空单元格的意思
第一行的2个g4表示:这个横向区域由2个g4单元格组成
第二行的两个g6同理
第三列的2个g1表示:这个竖向区域由2个g1单元格组成
这样做是不是很容易能做出任意想要的布局

指定单元格位置 grid-column-start、grid-column-end、grid-row-start、grid-row-end、grid-area

这4个属性指定单元格位置
grid-row-start 上边框所在的水平网格线
grid-row-end 下边框所在的水平网格线
grid-column-start 左边框所在的垂直网格线
grid-column-end 右边框所在的垂直网格线

grid-area: grid-row-start / grid-row-end / grid-column-start / grid-column-end 是上面四个属性的简写形式
例如: grid-area: 1/2/2/3; 表示
grid-row-start: 1;
grid-row-end: 2;
grid-column-start: 2;
grid-column-end: 3

多种值设定形式,这里只列举了几种,感兴趣的可以自行搜索。
grid-area: grid-row-start
grid-area: grid-row-start / grid-column-start
grid-area: grid-row-start / grid-row-end / grid-column-start
grid-area: span 2
1
2
3
4
5
6
1
2
3
4
5
6
grid-column-start:1;/*区域左边 第1个垂直线 开始*/
grid-column-end:3;/*区域右边 第3个垂直线 结束*/
grid-row-start:1;/*区域上边 第1个垂直线 开始*/
grid-row-end:3/*区域下边 第3个垂直线 结束*/
上面可以理解为让第三个div宽2格高2格,起始位置在第一格
1
2
3
4
5
6
.grid div:nth-child(3){
  grid-row-start:1; 
}
如果能达到效果,这4个属性可以只写其中几条,比如我想让第三个div排到首位只需要设定grid-row-start在第一个垂直线即可,其他都不用定义。
1
2
3
4
5
6
.grid div:nth-child(3){
  grid-column-start:1;
  grid-column-end:span 3;
}
上面表示:列起始在第一条垂直线,grid-column-end:span 3表示横跨三个单元格
由于第三个div占了3个单元格,第二个div后面放不下,就自动换了第二行,那么第一行是不是空了一块,很难看,那就引来了下一个属性grid-auto-flow

自动布局 grid-auto-flow

起初,我看到这个属性以为就是为瀑布流准备的,然而要想实现瀑布流还得配合js。上面示例中第一行空了一列,那用这个属性就可以弥补,让能放下的单元格自动放到那个位置,如下:
1
2
3
4
5
6
在容器的样式中加入下面这行属性即可
grid-auto-flow: row dense;
grid-auto-flow 默认值为row,放置顺序是"先行后列"。row dense表示尽可能填满容器,所以才有了第4个div填充到第一行第三列上。
既然有row,那肯定也有column,这就不演示了,用法一样,只不过一个是行,一个是列

容器内单元格内容水平垂直位置 justify-items、align-items、place-items

这个是作用容器内所有单元格,后面还有个作用于指定单元格的,注意区分
justify-items: start | end | center | stretch;
align-items: start | end | center | stretch;
place-items:是justify-items和align-items的简写形式
比如place-items:center center,如果两个值相同,可简写成一个 place-items:center

stretch默认值:拉伸,占满单元格的整个宽度。
start:对齐单元格的起始边缘。
end:对齐单元格的结束边缘。
center:单元格内部居中。
1
2
3
4
5
6
justify-items:start;
justify-items:end;
justify-items:center;
justify-items:stretch;
align-items:start;
align-items:end;
align-items:center;
align-items:stretch;
单元格里的内容水平垂直居中

容器内容水平垂直位置 justify-content,align-content,place-content

取值:start | end | center | stretch | space-around | space-between | space-evenly
还记得前面介绍auto-fill的示例中,右侧空余了10px吗,用这个两个属性就能控制容器内的内容位置
1
2
3
4
5
6
7
8
9
10
justify-content:start;
justify-content:end;
justify-content:center;
justify-content:stretch;
justify-content:space-around;
justify-content:space-between;
justify-content:space-evenly;
align-content:start;
align-content:end;
align-content:center;
align-content:stretch;
align-content:space-around;
align-content:space-between;
align-content:space-evenly;

指定单元格内容水平垂直位置 justify-self、align-self、place-self

指定单元格内容的水平位置,跟justify-items属性的用法完全一致,但只作用于单个项目
justify-self: start | end | center | stretch;
align-self: start | end | center | stretch;
place-self是justify-self和align-self简写形式
stretch默认值:拉伸,占满单元格的整个宽度。
start:对齐单元格的起始边缘。
end:对齐单元格的结束边缘。
center:单元格内部居中。

Grid的基本用法讲解完成,想要精通还需要不断实战,纸上谈兵可不行。

评论0 条

目录
  • Grid网格布局