你不了解的Grid布局

1,991 阅读9分钟

绿白色c4d活动运营海报(横版).png

快使用Grid布局 哼哼哈兮

快使用Grid布局 哼哼哈兮

前端之人切记 高效布局无敌

是谁在用Flexbox 费时费力

快使用Grid布局 哼哼哈兮

快使用Grid布局 哼哼哈兮

如果练会布局 网页飞檐走壁

10多年前,一位姓周的小生奉劝在座的各位,快使用双节棍,歌词字里行间可以看他十分迫切、焦急如焚的心情

10多年后,一位名howcode的程序员苦遭同行的重创——代码一把梭 flex,不禁发出苦天下久矣的感叹,立誓要将 Grid布局 发扬光大

如果你还没看过 就你小子还不会 Grid布局是吧? 这篇文章,强烈建议你先观看完再读本篇,因为本篇文章是续篇

响应式布局

111.gif

在过去,要实现上面的效果,代码千篇一律使用的都是媒体查询的技术

.parent {
  width: 90%;
  margin: 60px auto;
  display: grid;
  gap: 10px;
  grid-template-columns:repeat(4,1fr);
}
@media (max-width: 750px){
  .parent{
    grid-template-columns:repeat(3,1fr);
  }
}
@media (max-width: 500px){
  .parent{
    grid-template-columns:repeat(2,1fr);
  }
}

这样的代码写起来真是又长又臃余,Grid 想要实现这样的效果更简单了

鼠标移动至中间白色区域滑动改变区域大小

  • auto-fit:网格项会拉伸以填充整个网格容器的宽度,即便是在网格项不足以填满行时
  • minmax:定义的范围大于或等于 min, 小于或等于 max

注意:随着左边区域的减少,当宽度减少至 min的最小宽度时,此时子容器将溢出父容器

image.png

要修复也简单,我们再配合min函数即可

.parent {
  display: grid;
  grid-template-columns:repeat(auto-fit, minmax(min(100%,100px), 1fr));
}

再谈隐式与显式网格

什么是隐式网格与显式网格?

简单来说,当我们主动使用了grid-template-columnsgrid-template-rows属性来定义网格的列、行时,这时使用的就是显示网格,否则便是隐式网格

在此之前,先看一个简单的例子

我们在最外层盒子里,使用了grid布局

image.png

可以看的出,加上grid布局,和不加上时都是无明显变化的,但如果我们此时想把时间标签放到与标题并排时,可以这么给time样式添加以下属性

.time{
  grid-column-start: 2;
}

image.png

是不是很牛掰🤙,父容器被划分成了两列,而且时间也被分配到了第二列

😑但是美中不足的是:计划中最后一项持续写作,把更多技术分享给大家由于内容过长被折叠起来了,明明右侧还有足够空间,却因为父容器被划分两列后,导致计划的容器被分配到一列,空间不足而换行

有没有办法让计划这项占据两列呢?牛逼的Grid怎么可能没想到呢!

333.gif

使用grid-column属性

 .plan-list{
  grid-column: span 2;
  /* 等同于下面写法*/
  /* grid-column: 1 / 3; */
}

image.png

仔细观察上图,我们可以发现grid布局分配的两列区域大小不一,原来grid分配列空间时,先看两列的空间分配完后是否还存在剩余空间,如果存在则每列均分剩余空间

微信截图_20250205164555.png

但是我们如果需要每列平均的分配空间,是否可以做到?

so easy,只需要给父容器增加以下属性即可

.grid {
  display: grid;
  grid-auto-columns: 1fr;
}

image.png

完整代码

聊了那么多,你应该有灵敏的嗅觉,能察觉到grid布局的强大之处,并且脑海里能想象到一些复杂的布局可以用grid布局来解决,而不是flex,又或者float,甚至position:absolute

太对了,就是特殊的无序布局,例如以下布局

image.png

这种布局,flex难以胜任,更多的人想到的应该相对定位,但试想,我们可以把这种布局切割成网格

image.png

切分成网格之后,再根据刚刚学会的知识,就很容易完成这种复杂布局啦~

对齐方式

在默认情况下,如果我们没有指定子容器的宽度和高度,子容器都是被拉伸以填充整个网格容器

假设我们指定一个网格宽度是400px,两个子容器宽度为100px,此时网格右边还有剩余的空间

看到这么多的剩余空间,我好想控制它们怎么办?😈

Grid当然允许你操控子容器的对齐方式,这点和Flexbox布局很像,我们可以使用justify-content属性控制列的分布:

在这点上是不是和Flexbox布局的控制方式一模一样!虽然CSS Grid建立是在Flexbox基础上,但又将其进一步发展

最大的区别是我们对齐的是,而不是项目本身。从本质上讲,justify-content让我们安排网格的隔间,按照我们的意愿将它们分布在网格上

如果我们想它们的列中对齐项目本身,我们可以使用justify-items属性,我们尝试改造下上面的demo,将孩子容器的大小去掉

Grid布局默认会将孩子容器的大小拉伸到列分配的空间大小,这点和Flow布局中的<div>将水平拉伸以填充其容器很像,但使用justify-items就可以轻松打破布局

不过这个属性将对全部的子容器产生影响,如果你仅仅只需要控制特定的子容器做出控制,有办法做到吗?

444.jpeg

我就不吓你啦,当然是轻松可以胜任!有请我们的justify-self属性登场

行对齐

在上面,我们深入了解了如何在水平方向上对齐内容,如果你需要实现垂直方向上对齐内容,CSS Grid也是支持的

align-content类似于justify-content,但它影响行而不是列。类似地,align-items类似于justify-items,但它处理网格区域内项目的垂直对齐,而不是水平对齐

类似的,除了justify-self,还有align-self。此属性控制单个网格项在其单元格中的垂直位置,在此就不多作演示

双线定点

在聊这个特性之前,不妨打开刚刚的demo,并且F12查看.parent的元素css

image.png

是不是发现了一丝丝的不对劲,我代码中明明没有设置过place-contentplace-items这俩玩意,它们是从哪来的?

聪明的你应该能想到

place-contentjustify-content + align-content 的简写

place-itemsjustify-items + align-items 的简写

这就是我最后想塞给你的糖,它叫语法糖,也是我最喜欢的CSS网格小技巧之一

仅使用两个CSS属性,我们就可以在容器中水平和垂直地居中一个孩子

恭喜你,又掌握了一种将div元素居中的方法,快去吊打面试官吧!

奇门技巧

repeat

display:grid;
grid-template-columns:100px 1fr 1fr;
/* 等于以下写法 */
grid-template-columns:100px repeat(2,1fr);

如果你的布局是第一列占1fr,第二列占2fr,第三列1fr,第四列2fr...一直循环3次,可以写成如下

display:grid;
grid-template-columns:repeat(3,1fr 2fr);

瀑布流布局

22.png

如果你想实现如图所示中的瀑布流布局,在以往是需要自行实现的

但Grid却支持瀑布流布局,你只需要设置:

grid-template-rows: masonry;

详情可以查看:developer.mozilla.org/en-US/docs/…

遗憾的是:目前这个属性仅在火狐浏览器才支持,并且需要修改本地浏览器的配置才会生效

333.png

更多

image.png

  • CSS Grid布局生成器:特别推荐,很多复杂的布局,用这个网站在线就能快速实现并且获取到css相关的代码了

image.png

后话

花了很多时间来写这两篇Grid布局的教程,第一篇也收获了很多朋友的认可,这是我持续创造的源泉之一

但我要告诉你一个很残忍的现实:Grid布局或许很难流行起来

在写这些文章之前,我参考了很多的资料,并且在一篇关于Grid布局的爆款文章里面,发现了CSS大神张鑫旭对Grid布局的评论

微信截图_20250205212934.png

是呀,它确实不好学,这妨碍了它的普及性。但思考一件事,我们在学一个知识的时候,为什么要看它的普及性呢?我们应该更思考的是:这件事对我们本身是否有帮助?

红黑树、正则、Rust编程难学吧?但这又影响了什么?

我想告诉你的:不要畏惧难学而不学,这只会成为你和其他人拉开距离的地方

其次,我对比了很多篇文章的写作特点,尽量避免白话文,上来就告诉Grid的某个属性,写一堆又长又燥的文字,这样也不利于学习的欲望

我尽可能的先告诉你一些使用场景,再结合大量的demo试图让你更好的去接受Grid,这是我目前所能做到的最大的努力了。每个demo都消费了我很多的时间,如果有幸帮助到你,我很荣幸

那关于Grid布局的内容就到此结束了,下课!!

如果你对技术/行业交流有兴趣,欢迎添加howcoder微信,邀你进群交流

往期精彩

《就你小子还不会 Grid布局是吧?》

《超硬核:从零到一部署指南》

《私活2年,我赚到了人生的第一桶金》

《接入AI后,开源项目瞬间有趣了😎》

《肝了两个月,我们无偿开源了》

《彻底不NG前端路由》

《vue项目部署自动检测更新》

《一个公告滚动播放功能引发的背后思考》

《前端值得学习的开源socket应用》