快使用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 想要实现这样的效果更简单了
鼠标移动至中间白色区域滑动改变区域大小
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
属性来定义网格的列、行时,这时使用的就是显示网格,否则便是隐式网格
在此之前,先看一个简单的例子
我们在最外层盒子里,使用了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;
}
完整代码
聊了那么多,你应该有灵敏的嗅觉,能察觉到grid布局的强大之处,并且脑海里能想象到一些复杂的布局可以用grid布局来解决,而不是flex
,又或者float
,甚至position:absolute
太对了,就是特殊的无序布局,例如以下布局
这种布局,flex难以胜任,更多的人想到的应该相对定位,但试想,我们可以把这种布局切割成网格
切分成网格之后,再根据刚刚学会的知识,就很容易完成这种复杂布局啦~
对齐方式
在默认情况下,如果我们没有指定子容器的宽度和高度,子容器都是被拉伸以填充整个网格容器
假设我们指定一个网格宽度是400px,两个子容器宽度为100px,此时网格右边还有剩余的空间
看到这么多的剩余空间,我好想控制它们怎么办?😈
Grid
当然允许你操控子容器的对齐方式,这点和Flexbox
布局很像,我们可以使用justify-content
属性控制列的分布:
在这点上是不是和Flexbox
布局的控制方式一模一样!虽然CSS Grid建立是在Flexbox基础上,但又将其进一步发展
最大的区别是我们对齐的是列,而不是项目本身。从本质上讲,justify-content
让我们安排网格的隔间,按照我们的意愿将它们分布在网格上
如果我们想在它们的列中对齐项目本身,我们可以使用justify-items
属性,我们尝试改造下上面的demo,将孩子容器的大小去掉
Grid布局默认会将孩子容器的大小拉伸到列分配的空间大小,这点和Flow布局中的<div>
将水平拉伸以填充其容器很像,但使用justify-items
就可以轻松打破布局
不过这个属性将对全部的子容器产生影响,如果你仅仅只需要控制特定的子容器做出控制,有办法做到吗?
我就不吓你啦,当然是轻松可以胜任!有请我们的justify-self
属性登场
行对齐
在上面,我们深入了解了如何在水平方向上对齐内容,如果你需要实现垂直方向上对齐内容,CSS Grid也是支持的
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属性,我们就可以在容器中水平和垂直地居中一个孩子
恭喜你,又掌握了一种将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);
瀑布流布局
如果你想实现如图所示中的瀑布流布局,在以往是需要自行实现的
但Grid却支持瀑布流布局,你只需要设置:
grid-template-rows: masonry;
详情可以查看:developer.mozilla.org/en-US/docs/…
遗憾的是:目前这个属性仅在火狐浏览器才支持,并且需要修改本地浏览器的配置才会生效
更多
- CSS Grid布局练习网站:一个让你在线练习grid布局的网站,对新手十分友好,玩游戏一样学习代码
- CSS Grid布局生成器:特别推荐,很多复杂的布局,用这个网站在线就能快速实现并且获取到css相关的代码了
后话
花了很多时间来写这两篇Grid
布局的教程,第一篇也收获了很多朋友的认可,这是我持续创造的源泉之一
但我要告诉你一个很残忍的现实:Grid布局或许很难流行起来
在写这些文章之前,我参考了很多的资料,并且在一篇关于Grid
布局的爆款文章里面,发现了CSS大神张鑫旭对Grid布局的评论
是呀,它确实不好学,这妨碍了它的普及性。但思考一件事,我们在学一个知识的时候,为什么要看它的普及性呢?我们应该更思考的是:这件事对我们本身是否有帮助?
红黑树、正则、Rust编程难学吧?但这又影响了什么?
我想告诉你的:不要畏惧难学而不学
,这只会成为你和其他人拉开距离的地方
其次,我对比了很多篇文章的写作特点,尽量避免白话文,上来就告诉Grid
的某个属性,写一堆又长又燥的文字,这样也不利于学习的欲望
我尽可能的先告诉你一些使用场景,再结合大量的demo试图让你更好的去接受Grid
,这是我目前所能做到的最大的努力了。每个demo都消费了我很多的时间,如果有幸帮助到你,我很荣幸
那关于Grid布局的内容就到此结束了,下课!!
如果你对技术/行业交流有兴趣,欢迎添加howcoder
微信,邀你进群交流