grid 实现完美的水平铺满、间隔一致的自适应布局

需求描述

  • 在一个容器元素下,有不确定数量的子元素,要求他们水平铺满,并且在当前行的最左边和最右边的子元素距离父元素左边缘和右边缘都是无缝贴合的。
  • 每个子元素之间的间隔必须一致。
  • 当浏览器窗口大小变动自适应。

尝试方案

惯性思维,一眼看过去就是 flex弹性盒子 一把梭,于是我有了以下这种方案:

index.html 文件

html 复制代码
<body>
  <div class="father">
    <div class="child">Child1</div>
    <div class="child">Child2</div>
    <div class="child">Child3</div>
    <div class="child">Child4</div>
    <div class="child">Child5</div>
    <div class="child">Child6</div>
    <div class="child">Child7</div>
    <div class="child">Child8</div>
    <div class="child">Child9</div>
    <div class="child">Child10</div>
  </div>
</body>

index.scss 文件

css 复制代码
.father {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: flex-start;
  width: 100%;
  padding: 10px 0 10px 20px;

  .child {
    margin-right: 14px;
    margin-bottom: 14px;
    // 其他卡片样式
  }
}

可以看到,我会为每个子元素都设置 margin-top 以及 margin-right 来固定他们之间的间距,但是因为每一行最右边的子元素也有 margin-right ,为了补偿这个,我就将父元素的 padding-right 去掉了,这样做的坏处太多了,需要自己去计算,做补偿,而且右边有时候容纳不下一个完整的子元素,就会导致换行而留下一大片白。。

改进方案

Flex 布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局。Grid 布局则是将容器划分成"行"和"列",产生单元格,然后指定"项目所在"的单元格,可以看作是二维布局。Grid 布局远比 Flex 布局强大

首先我们需要给容器指定为 grid 网格布局,就像 flex 一样:

css 复制代码
.father {
  display: grid;
}

接着要为其划分列数, grid-template-columns 属性可定义每一列的列宽,假如代码如下,我们将容器划分成 3 列,每列宽度为容器的 100px

css 复制代码
.father {
  grid-template-columns: 100px 100px 100px;
}

但是这个时候我们看到的效果会是下面这样:

子元素并没有把父元素占满,这显然不是我们想要的效果,幸亏有 repeat() 函数帮助我们简化重复值, 它接受两个参数,第一个参数是重复的次数,第二个参数是所要重复的值 。上面的代码完全可用以下代码代替:

css 复制代码
.father {
  grid-template-columns: repeat(3, 100px);
}

当然,这只是第一步,我们还需要借助 auto-fill 关键字,在我们需要容器能尽可能容纳子元素时,就需要用到它,表示自动填充,我的理解是 repeat() 接受了这个 auto-fill 的参数时,会去自动计算容纳的数量,就好像你事先算出来这个容器能容纳多少子元素,然后把这个"多少"传给该函数一样。这时候代码如下:

css 复制代码
.father {
  display: grid;
  grid-template-columns: repeat(auto-fill, 100px);
}

现在图形如下,已经越来越接近我们的目标了:

但是很显然,右边有一个空隙, justify-content 属性拯救我们,它整个内容区域在容器里面的水平位置,当我设置其为 space-between 时,意味着子元素之间的间隔相等,而子元素与容器边框之间没有间隔

不过子元素之间还是没有间隔,简单设置一下属性 gap 即可,它是 column-gaprow-gap 的合并简写,分别表示列与列行与行之间的间距,现在代码如下:

css 复制代码
.father {
  display: grid;
  grid-template-columns: repeat(auto-fill, 100px);
  justify-content: space-between;
  gap: 14px 4px;
}

由此简单的几行代码就已经完美实现了我们想要的效果:

当然,注意一下 grid 网格布局的兼容性

相关推荐
yuki_uix5 分钟前
AI辅助网页设计:从图片到代码的实践探索
前端
我想说一句5 分钟前
事件机制与委托:从冒泡捕获到高效编程的奇妙之旅
前端·javascript
陈随易6 分钟前
MoonBit助力前端开发,加密&性能两不误,斐波那契测试提高3-4倍
前端·后端·程序员
小飞悟12 分钟前
你以为 React 的事件很简单?错了,它暗藏玄机!
前端·javascript·面试
中微子19 分钟前
JavaScript 事件机制:捕获、冒泡与事件委托详解
前端·javascript
Whoisshutiao36 分钟前
网安-XSS-pikachu
前端·安全·网络安全
惊鸿28741 分钟前
Taro3+小程序Canvas动态生成海报和二维码分享到朋友圈
前端
做梦都在学习前端1 小时前
发布一个monaco-editor 汉化包
前端·npm·vite
石小石Orz1 小时前
为什么推荐前端学习油猴脚本开发?
前端
珵煜ini1 小时前
wd-button组件阻止事件冒泡的
前端