原创 howcode 2025-02-23 09:02 重庆
点击关注公众号,“技术干货” 及时达!
❝快使用Grid布局 哼哼哈兮
快使用Grid布局 哼哼哈兮
前端之人切记 高效布局无敌
是谁在用Flexbox 费时费力
快使用Grid布局 哼哼哈兮
快使用Grid布局 哼哼哈兮
如果练会布局 网页飞檐走壁
❞
10多年前,一位姓周的小生奉劝在座的各位,快使用双节棍,歌词字里行间可以看他十分迫切、焦急如焚的心情
10多年后,一位名howcode的程序员苦遭同行的重创——代码一把梭 flex,不禁发出「苦天下久矣」的感叹,立誓要将 Grid布局 发扬光大
如果你还没看过 就你小子还不会 Grid布局是吧?这篇文章,强烈建议你先观看完再读本篇,因为本篇文章是续篇
响应式布局
在过去,要实现上面的效果,代码千篇一律使用的都是媒体查询的技术
.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 想要实现这样的效果更简单了
鼠标移动至中间白色区域滑动改变区域大小
jcode
auto-fit:网格项会拉伸以填充整个网格容器的宽度,即便是在网格项不足以填满行时
minmax:定义的范围大于或等于 min, 小于或等于 max
「注意」:随着左边区域的减少,当宽度减少至 min的最小宽度时,此时子容器将溢出父容器
要修复也简单,我们再配合min函数即可
.parent {display: grid;grid-template-columns:repeat(auto-fit, minmax(min(100%,100px), 1fr));}
再谈隐式与显式网格
什么是隐式网格与显式网格?
简单来说,当我们主动使用了grid-template-columns或grid-template-rows属性来定义网格的列、行时,这时使用的就是显示网格,否则便是隐式网格
在此之前,先看一个简单的例子
jcode
我们在最外层盒子里,使用了grid布局
可以看的出,加上grid布局,和不加上时都是无明显变化的,但如果我们此时想把时间标签放到与标题并排时,可以这么给time样式添加以下属性
.time{grid-column-start: 2;}
是不是很牛掰?,父容器被划分成了两列,而且时间也被分配到了第二列
?但是美中不足的是:计划中最后一项持续写作,把更多技术分享给大家由于内容过长被折叠起来了,明明右侧还有足够空间,却因为父容器被划分两列后,导致计划的容器被分配到一列,空间不足而换行
有没有办法让计划这项占据两列呢?牛逼的Grid怎么可能没想到呢!
使用grid-column属性
.plan-list{grid-column: span 2;/* 等同于下面写法*//* grid-column: 1 / 3; */}
仔细观察上图,我们可以发现grid布局分配的两列区域大小不一,原来grid分配列空间时,先看两列的空间分配完后是否还存在剩余空间,如果存在则每列均分剩余空间
但是我们如果需要每列平均的分配空间,是否可以做到?
so easy,只需要给父容器增加以下属性即可
.grid {display: grid;grid-auto-columns: 1fr;}
完整代码
jcode
聊了那么多,你应该有灵敏的嗅觉,能察觉到grid布局的强大之处,并且脑海里能想象到一些复杂的布局可以用grid布局来解决,而不是flex,又或者float,甚至position:absolute
太对了,就是特殊的无序布局,例如以下布局
这种布局,flex难以胜任,更多的人想到的应该相对定位,但试想,我们可以把这种布局切割成网格
切分成网格之后,再根据刚刚学会的知识,就很容易完成这种复杂布局啦~
jcode
对齐方式
在默认情况下,如果我们没有指定子容器的宽度和高度,子容器都是被拉伸以填充整个网格容器
假设我们指定一个网格宽度是400px,两个子容器宽度为100px,此时网格右边还有剩余的空间
jcode
看到这么多的剩余空间,我好想控制它们怎么办??
Grid当然允许你操控子容器的对齐方式,这点和Flexbox布局很像,我们可以使用justify-content属性控制列的分布:
jcode
在这点上是不是和Flexbox布局的控制方式一模一样!虽然CSS Grid建立是在Flexbox基础上,但又将其进一步发展
最大的区别是我们对齐的是列,而不是项目本身。从本质上讲,justify-content让我们安排网格的隔间,按照我们的意愿将它们分布在网格上
如果我们想在它们的列中对齐项目本身,我们可以使用justify-items属性,我们尝试改造下上面的demo,将孩子容器的大小去掉
jcode
Grid布局默认会将孩子容器的大小拉伸到列分配的空间大小,这点和Flow布局中的<div>将水平拉伸以填充其容器很像,但使用justify-items就可以轻松打破布局
不过这个属性将对全部的子容器产生影响,如果你仅仅只需要控制特定的子容器做出控制,有办法做到吗?
我就不吓你啦,当然是轻松可以胜任!有请我们的justify-self属性登场
jcode
行对齐
在上面,我们深入了解了如何在水平方向上对齐内容,如果你需要实现垂直方向上对齐内容,CSS Grid也是支持的
jcode
align-content类似于justify-content,但它影响行而不是列。类似地,align-items类似于justify-items,但它处理网格区域内项目的垂直对齐,而不是水平对齐
类似的,除了justify-self,还有align-self。此属性控制单个网格项在其单元格中的垂直位置,在此就不多作演示
双线定点
在聊这个特性之前,不妨打开刚刚的demo,并且F12查看.parent的元素css
是不是发现了一丝丝的不对劲,我代码中明明没有设置过place-content、place-items这俩玩意,它们是从哪来的?
聪明的你应该能想到
place-content:justify-content + align-content 的简写
place-items:justify-items + align-items 的简写
这就是我最后想塞给你的糖,它叫语法糖,也是我最喜欢的CSS网格小技巧之一
仅使用两个CSS属性,我们就可以在容器中水平和垂直地居中一个孩子
jcode
恭喜你,又掌握了一种将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);
jcode
瀑布流布局
如果你想实现如图所示中的瀑布流布局,在以往是需要自行实现的
但Grid却支持瀑布流布局,你只需要设置:
grid-template-rows: masonry;详情可以查看:https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout/Masonry_layout
遗憾的是:目前这个属性仅在火狐浏览器才支持,并且需要修改本地浏览器的配置才会生效
更多
CSS Grid布局练习网站:一个让你在线练习grid布局的网站,对新手十分友好,玩游戏一样学习代码
CSS Grid布局生成器:特别推荐,很多复杂的布局,用这个网站在线就能快速实现并且获取到css相关的代码了
后话
花了很多时间来写这两篇Grid布局的教程,第一篇也收获了很多朋友的认可,这是我持续创造的源泉之一
但我要告诉你一个很残忍的现实:Grid布局或许很难流行起来
在写这些文章之前,我参考了很多的资料,并且在一篇关于Grid布局的爆款文章里面,发现了CSS大神张鑫旭对Grid布局的评论
是呀,它确实不好学,这妨碍了它的普及性。但思考一件事,我们在学一个知识的时候,为什么要看它的普及性呢?我们应该更思考的是:这件事对我们本身是否有帮助?
红黑树、正则、Rust编程难学吧?但这又影响了什么?
我想告诉你的:不要畏惧难学而不学,这只会成为你和其他人拉开距离的地方
其次,我对比了很多篇文章的写作特点,尽量避免白话文,上来就告诉Grid的某个属性,写一堆又长又燥的文字,这样也不利于学习的欲望
我尽可能的先告诉你一些使用场景,再结合大量的demo试图让你更好的去接受Grid,这是我目前所能做到的最大的努力了。每个demo都消费了我很多的时间,如果有幸帮助到你,我很荣幸.
那关于Grid布局的内容就到此结束了,下课!!
点击关注公众号,“技术干货” 及时达!
