介绍

之前写过两篇文章,分别讲解了Flex布局和网格布局。然后有很多人反馈说。网格布局没有场景,学会Flex布局就可以了。
今天这篇文章就通过一个例子来讲解一下网格布局的优势。并不是说Flex布局无法实现。而是说在某些场景下使用Flex布局逻辑会不清晰,代码会复杂很多。

手机桌面的小组件

今天要举的例子就是从手机桌面上面来的。现在的手机桌面上,可以自定义的放一些App图标,也可以添加很多小组件。就拿我的苹果手机来举例。一个桌面,它会有4列的图标,然后在这些桌面上可以任意添加小组件。小组件可能是一行4列或者是两行两列等各种情况。

如果我们用前端页面来实现这种效果的话,该怎么做呢?

Flex实现

大家可以先自己想想看这种布局用Flex该怎么实现。

如果使用Flex布局的方式来实现这个需求。我们会发现使用Flex布局会很麻烦,需要用js去提前计算,当前行是否存在一行多列的组件,或者多行一列的组件。得出布局结构后,再去做第一层的div,以及第二层div

这里的逻辑太麻烦,我就不写了。有兴趣可以自己去尝试写写看。

Grid实现

首先会有一个父节点。他是一个是列多行的网格容器。为了避免留下空白,我们设置自动布局算法为dense

<div class="grid-box" id="box"></div>

下面是CSS:

.grid-box {
  border: 1px solid #999;
  width: 200px;
  height: 400px;
  display: grid;
  margin: 20px;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(8, 1fr);
  gap: 6px;
  padding: 6px;
  grid-auto-flow: dense;
}
.grid-box > div {
  background-color: bisque;
  border-radius: 4px;
  border: 1px solid #ccc;
}

假设桌面的图标或小组件,可以选择1x1,1x2,2x1,2x2四种效果。所以我们可以先设置三种大小的子节点空间,因为默认是1x1,所以1x1不需要单独这种。有了这几个class我们创建子节点的时候,只要往上面添加这个对应的class就能实现对应的效果。

.grid-box-item-1 {
  grid-column-end: span 2; /* 1x2 */
}
.grid-box-item-2 {
  grid-row-end: span 2; /* 2x1 */
}
.grid-box-item-3 { /* 2x2 */
  grid-column-end: span 2;
  grid-row-end: span 2;
}

因为要控制随机位置,网格布局并不像Flex布局那样,可以指定子节点的顺序。所以这个子节点要通过JS往容器append

function randomItem() {
  let styleArr = [0,0,0,0,1,1,2,3];
  let itemsEl = '';
  for (let i = 0; i < styleArr.length; i++) {
    itemsEl += `<div class="grid-box-item-${styleArr[i]}">${i}</div>`;
  }

  boxEl.innerHTML = itemsEl;
}

randomItem();

效果如图:

最后我们对样式数组做一个随机。

function randomItem() {
  let styleArr = [0,0,0,0,1,1,2,3];
  styleArr = styleArr.sort(() => {
    return Math.random() > 0.5 ? 1 : -1;   
  });
  // ...
}

当我们每次重新调用randomItem方法之后,都会对子节点做一个随机的摆放。效果如图:

总结

还是上面的例子,如果布局结构是固定的,那么使用Flex布局其实也不复杂,但是一有变化,Flex就复杂了。

可以看出,使用Flex能够快速解决大部分的场景了,这个也就是之前很多人评论的,找不到使用Grid布局的场景,没必要学Grid布局。

但是一旦遇到一些特殊不情况,不知道Grid布局,就只能使用Flex,那么代码就会又臭又长。

结束

好了,本文到此结束,希望本文对你有所帮助 :-)
最近新弄了一个公粽号:写代码的浩,求关注 😄。后面会逐步把掌握的前端知识以及职场知识沉淀下来。
如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。


写代码的浩
80 声望7 粉丝