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 网格布局的兼容性

相关推荐
浪里行舟34 分钟前
国产OCR双雄对决?PaddleOCR-VL与DeepSeek-OCR全面解析
前端·后端
znhy@1231 小时前
CSS易忘属性
前端·css
瓜瓜怪兽亚1 小时前
前端基础知识---Ajax
前端·javascript·ajax
AI智能研究院1 小时前
(四)从零学 React Props:数据传递 + 实战案例 + 避坑指南
前端·javascript·react.js
qq7798233401 小时前
React组件完全指南
前端·javascript·react.js
qq7798233402 小时前
React Hooks完全指南
前端·javascript·react.js
Moment2 小时前
性能狂飙!Next.js 16 重磅发布:Turbopack 稳定、编译提速 10 倍!🚀🚀🚀
前端·javascript·后端
软件技术NINI2 小时前
html css js网页制作成品——HTML+CSS仙台有树电视剧网页设计(5页)附源码
javascript·css·html
DoraBigHead2 小时前
React Fiber:从“递归地狱”到“时间切片”的重生之路
前端·javascript·react.js
lecepin3 小时前
AI Coding 资讯 2025-10-22
前端·javascript·后端