玩转Grid布局

5,328 阅读4分钟

主菜

最近烧烤君接到一个需求,要实现像下图这样的效果:

这对烧烤君这种混迹烧烤市场多年的年轻人来说,三下五除二就可以烤出来,绝不浪得虚名!

但是,菜只有一种,而烤的手段可以有多种,所谓技多不压身!下面我们一起看看实现这种效果有多少种方式。

需求分析

一张简图描述一下需求

这种就是网格布局的具体案例!

父容器的宽自适应,子容器的宽计算公式为 (100% - (n - 1) * 24) / n 。如果页面宽度大于1280px,n等于5,小于1280px时,n等于4,页面最小宽度是960px;

根据这条计算公式我们可以得出以下处理方式。

Grid 布局

用Grid布局实现这种需求是最专业不过的了。Grid布局又名网格布局。

Grid布局的知识看阮大师的文章,一看就懂:《CSS Grid 网格布局教程 》

//html
<div class="parent">
	<div class="children">
    	<div class="children-content"></div>
    </div>
    ...
</div>

//css
//父容器
.parent {
	display: grid;
    grid-template-columns: repeat(5, 1fr);
    grid-row-gap: 24px;
    grid-column-gap: 24px;
}

@media screen and (max-width: 1280px) {
    .parent {
        grid-template-columns: repeat(4, 1fr);
    }
}

//子容器
.children {}

Grid布局的优点就是使用短小精悍的样式代码,实现很棒的UI布局,相对比传统的布局方式,Grid布局和flex布局一样,具备很高的效值!

但是它的缺点在于IE浏览器的兼容性不是很好,仅能部分属性兼容,如果要完全适配,那就得下一波功夫了!

浮动布局

很多同学一用到浮动布局就想到使用margin撑开距离,这种想法用css实现

//父容器
.parent {
	width: 100%;
}
//清楚浮动
.parent::after {
	content: '';
    display: block;
    height: 0;
    clear: both;
}
//子容器
.children {
	float: left;
	width: **px;
    height: **px;
    margin: **px **px;
}

写完上面的布局实现,发现并不能实现最初的功能,子容器的之间的距离是24px,这个距离是不随页面的缩放变化的,有的同学就采用了投机取巧的方式进行,将24px转变成百分比,就写出了下面欺骗自己人的答案:

//子容器 18.4 * 5 + 4 * 2 = 100;
.children {
	float: left;
	width: 18.4%;
    height: **px;
    margin-left: 2%;
}

需要100%还原设计需求毋庸置疑!

如何使用浮动布局完美实现?

从计算子容器宽度公式 (100% - (n - 1) * 24) / n 出发,转变一下:

childrenWidth = (100% - (n - 1) * 24) / n 
			  = (100% + 24 - n * 24) / n
			  = (100% + 24) / n - 24

从结果 (100% - 24) / n - 24 看,得到了这个解法。子容器的宽度需要包含间距24px,且父容器的宽度需要增加24px,也就是说子容器的宽度可以使用百分比表示,但是内涵24px额外的宽度。

如图所示:

代码实现:

//父容器强行增加24px
.parent {
	width: calc(100% + 24px);
}

.parent::after {
	content: '';
    display: block;
    height: 0;
    clear: both;
}

.children {
	float: left;
    width: 20%;
    margin-bottom: 24px;
    padding-right: 24px;
}

@media screen and (max-width: 1280px) {
    .children {
        width: 25% !important;
    }
}

.children-content {
	width: 100%;
}

//or
.parent {
	width: calc(100% + 24px);
    margin-left: -24px;
}

.parent::after {
	content: '';
    display: block;
    height: 0;
    clear: both;
}

.children {
	float: left;
    width: calc(25% - 24px);
    height: 40px;
    margin-bottom: 24px;
    margin-left: 24px;
    background-color: aquamarine;
}

@media screen and (max-width: 1280px) {
    .children {
        width: calc(25% - 24px) !important;
    }
}

这种做法缺点是增加了n个子容器顶级节点,这个节点有可能会影响子容器内的布局,谨慎使用这种方式。当然,这种做法的最大的好处是浏览器兼容性很不错,较吃兼容性的属性calc虽然在 can i use 中显示不是完全适配IE,但是上面这段代码是很ok的!

flex布局

还不懂flex布局的看阮大师的这篇 Flex 布局教程:语法篇

直接上实现方式:

.parent {
    width: calc(100% + 24px);
    margin-left: -24px;
    display: flex;
    flex-wrap: wrap;
}

.children {
    flex-basis: calc(20% - 24px);
    height: 40px;
    margin-bottom: 24px;
    margin-left: 24px;
    background-color: aquamarine;
}

@media screen and (max-width: 1280px) {
    .children {
        width: calc(25% - 24px) !important;
    }
}

可以看到,该实现方式和浮动布局的实现方式大同小异,所以,可以确定的是,这两种布局对于这种需求是不那么专业的!同时兼容性取决于calc和flex的兼容性。

但是,对于爱好使用flex布局的同学来说,flex也是可以实现的这种网格布局需求的。

总结

除了上面的集中布局形式可以实现需求,当然还有其他的实现方式,欢迎在评论区讨论,但是如果不考虑兼容性,看到这种需求,第一想到的就应该使用grid布局。

关注「前端烧烤摊」 掘金 or 微信公众号, 第一时间获取烧烤君的前端路上的总结与发现。