前端布局新朋友-网格布局

认识网格布局(Grid Layout)

相信学web前端的朋友们应该对“布局”这个概念不陌生吧,在前端布局里有这么几大布局技术:

  1. 流式布局(Flow Layout 默认)
  2. 浮动布局(Float Layout)
  3. 定位布局(Position Layout)
  4. 表格布局(Table Layout 已弃用)
  5. 框架布局(Frame Layout 不太常用)

CSS3之后新增了两个新布局

  1. 弹性布局(Flexbox Layout)
  2. 网格布局(Grid Layout)

之前用flex布局用着挺爽的,响应效果很强。然而为什么想起去接触网格布局这个东西呢?emmmm最近在做一个小程序,要实现的效果是这样的:在这里插入图片描述
发现箭头指着这一块的布局好复杂啊,首先它大体上一行有五列,然后每一列又各自有它的小布局,特别是第二列,我。。。
(以下省略对UI设计师的10000字吐槽)
在这里插入图片描述
于是我就想到了,好像有网格布局这么一个东西,用它应该挺合适的。虽说用浮动或者flex布局也能实现,但既然想到了就用呗,顺便长点见识。
好了,正片开始~
在这里插入图片描述
说起这个布局,或许大伙都想到了Bootstrap的栅格系统,没错!它俩挺像,我也这样觉得。
咱们接下来的讲解就用以下的HTML作为例子吧 ↓

<body>
	<div class="grid-box">
		<div class="item item1">1</div>
		<div class="item item2">2</div>
		<div class="item item3">3</div>
		<div class="item item4">4</div>
		<div class="item item5">5</div>
		<div class="item item6">6</div>
		<div class="item item7">7</div>
		<div class="item item8">8</div>
		<div class="item item9">9</div>
		<div class="item item10">10</div>
		<div class="item item11">11</div>
		<div class="item item12">12</div>
	</div>
</body>

要实现网格布局,首先要给布局的父盒子声明布局为网格布局(就像弹性布局一样要先用display: flex;声明一下),网格布局跟弹性布局的实现方式有点像,它也分为 容器子项目

display: grid; //让容器变为网格布局容器,当然你也可以赋值inline-grid,让容器同时带有内联元素的特性。

另外需要注意

注:当元素设置了网格布局,它的全部子项目所具有的column、float、clear、vertical-align属性均会失效。

接下来给容器划分网格,需要用到以下两个属性。

  • grid-template-rows
  • grid-template-columns

见名知意,它定义网格布局应该有几行几列,比如

.grid-box {
	display: grid;
	grid-template-rows: 150px 150px 150px 150px;  /* 它的值有四项,代表现在的网格有四行 */
	grid-template-columns: 300px 1fr 300px;  /* 它的值有三项,代表现在的网格有三列 */
}

我们来看看效果,在这之前先给它赋予显示样式

.item{
	border: 1px solid #000;
	font-size: 50px;
}
.item:nth-child(odd) {
	background-color: aqua;
	color: #fff;
}
.item:nth-child(even) {
	background-color: hotpink;
	color: #000;
}

然后效果就很明显了,如下
在这里插入图片描述

以上提到的这两个属性的值,它的表示方法可以有以下几种

  • 具体的像素值
  • 百分值
  • 带等分单位fr的值
  • 使用函数repeat()表示的值

等分单位fr

CSS3专门为网格布局设计了一个新的单位,它就是fr,来自英文单词fraction(均分、等分)。怎么理解呢?直接上demo!

grid-template-columns: 1fr 1fr 1fr 1fr;
/* 它等价于 */
grid-template-columns: 25% 25% 25% 25%;

grid-template-columns: 1fr 2fr 1fr;
/* 它等价于 */
grid-template-columns: 25% 50% 25%;

哈,简单明了!现在你应该明白这个单位了叭

带函数repeat()表示的值

有时候你需要给网格定义相同宽的列或者相同高的行,两三行(列)还好说,要是十几行呢?想象一下。。。↓

/* 给网格定义12列等宽的列 */
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;

天哪!这太可怕了吧。。。
其实,你可以这样做

grid-template-columns: repeat(12, 1fr);

它等价于本节的第一句css代码。
它还可以重复循环某一个规则,比如

grid-template-columns: repeat(2, 1fr 2fr);
/* 等价于 */
grid-template-columns: 1fr 2fr 1fr 2fr;

看!repeat很方便有木有

grid-gap单元格间距

再回到刚才的效果图,此时网格的各个单元格之间没有间距,你可以通过插入间距实现如下效果
在这里插入图片描述
此时就需要用到另一个属性grid-gap,它属于网格容器的属性。也就是说,这个属性应写在网格容器中而不是子项目中

.grid-box {
	display: grid;
	grid-template-rows: 150px 150px 150px 150px;
	grid-template-columns: 300px 1fr 300px;
	grid-gap: 10px;   /* 给单元格插入10px的间距 */
}

其实,我觉得吧,这个属性好像跟单纯给子项目加margin没有啥区别,至少我目前是这样认为的。

语法
grid-gap: 行间距 列间距;  (如果只写一个值,则默认行列间距共用一个值),如
grid-gap: 10px 20px;

它还可以分开写,形式如下

grid-row-gap: 10px;
grid-column-gap: 20px;

在这里插入图片描述
根据w3c标准,grid-gap、grid-row-gap、grid-column-gap这三个属性还可以省略grid-前缀,即写成gap、row-gap以及column-gap。

单元格的位置定位

在讲这一部分之前,我们先来认识几个概念,网格线和网格轨道

网格线
引用阮一峰阮大神的一张图 ↓
在这里插入图片描述
每根网格线都有它一个唯一的序号

网格轨道
即任意两条平行网格线之间夹着的区域。
好了,相信大家对于这两个概念应该明白了吧。(真是一图胜千言啊hhhhhh)
那么接下来就要介绍关于网格线定位的属性了,主要有以下四个

  1. grid-row-start(定位单元格的上网格线)
  2. grid-row-end(定位单元格的下网格线)
  3. grid-column-start(定位单元格的左网格线)
  4. grid-column-end(定位单元格的右网格线)

要理解它们也很容易,直接上demo(实现将9移到2的位置)
在这里插入图片描述
代码如下

.item:nth-child(9) {
	grid-row-start: 1;
	grid-row-end: 2;
	grid-column-start: 2;
	grid-column-end: 3;
}
/* 注意这些网格线定位属性都是写在子项目里的,不能写在网格容器上 */

如果你觉得看到这里还是懵逼的话,那么看下图的原理解释。
在这里插入图片描述

单元格合并

有时候我们布局时并不需要这样规规整整,有时需要合并某些单元格。那么可以这样做,让grid-row-end和grid-column-end往后再挪一挪就好了。

/* 让9号单元格往右扩展一个单元格单位 */
.item:nth-child(9) {
	grid-row-start: 1;
	grid-row-end: 2;
	grid-column-start: 2;
	grid-column-end: 4;  /* 仔细对比此处 */
}

在这里插入图片描述

/* 让9号单元格往下扩展一个单元格单位 */
.item:nth-child(9) {
	grid-row-start: 1;
	grid-row-end: 3; /* 仔细对比此处 */
	grid-column-start: 2;
	grid-column-end: 3; 
}

在这里插入图片描述
其实,合并单元格还有另外一种写法

grid-row-end: span 跨度; 
grid-column-end: span 跨度; 
/* 另外,当跨度是1时,grid-*-end可以省略 */

如上一个例子咱们可以这样写

.item:nth-child(9) {
	grid-row-start: 1;
	grid-row-end: span 2;
	grid-column-start: 2;
	/* grid-column-end可省略 */
}

最后

讲到这里,不知各位对于grid布局跟flex布局有啥区别吗? 我反正想到了一点,flex是一维布局(整个布局是有一条条主轴堆叠而成),而grid是二维布局(在一定程度上方便了整体的布局),在实际应用中建议flex布局和grid布局交错搭配,这样能达到很完美的自适应和响应式效果。
由于整个grid布局的知识体系太大了,所以本期就打算先这样了,临时决定分两期哈哈哈哈。相信我!下一期一定给大伙讲完,拜拜~

发布了20 篇原创文章 · 获赞 6 · 访问量 4040

猜你喜欢

转载自blog.csdn.net/CanMoHaiYan/article/details/92850978