移除 CSS 网格中的宽间隙

Remove wide gaps in CSS Grid

我使用 css 网格进行了设计,这让我在行之间产生了意想不到的 space。我使用以下代码重现了我的问题:

main {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}
article {
  background: red;
}
.item1 {
  height: 30px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 1;
  grid-row-end: 2;
}
.item2 {
  height: 100px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 2;
  grid-row-end: 3;
}
.item3 {
  height: 300px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 3;
  grid-row-end: 4;
}
.item4 {
  height: 490px;
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 5;
}
.item5 {
  height: 160px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 4;
  grid-row-end: 6;
}
.item6 {
  height: 520px;
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 5;
  grid-row-end: 7;
}
.item7 {
  height: 300px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 6;
  grid-row-end: 7;
}
<main>
  <article class="item1"></article>
  <article class="item2"></article>
  <article class="item3"></article>
  <article class="item4"></article>
  <article class="item5"></article>
  <article class="item6"></article>
  <article class="item7"></article>
</main>

在这里您可以看到底部项目顶部的额外间隙。

我发现了一个类似的问题 -- -- 额外的差距是由数字引起的,并使用数字上的 display: flex 解决了,但这对我不起作用。

有什么想法吗?


编辑:

我的示例具有误导性,这是一个更接近实际问题的版本:

main {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}
article {
  background: red;
}
article div {
  background: blue;
}
.item1 {
  grid-column-start: 1;
  grid-column-end: span 1;
  grid-row-start: 1;
  grid-row-end: span 1;
}
.item1 div {
  height: 30px;
}
.item2 {
  grid-column-start: 1;
  grid-column-end: span 1;
  grid-row-start: 2;
  grid-row-end: span 1;
}
.item2 div {
  height: 100px;
}
.item3 {
  grid-column-start: 1;
  grid-column-end: span 1;
  grid-row-start: 3;
  grid-row-end: span 1;
}
.item3 div {
  height: 300px;
}
.item4 {
  grid-column-start: 2;
  grid-column-end: span 1;
  grid-row-start: 1;
  grid-row-end: span 4;
}
.item4 div {
  height: 490px;
}
.item5 {
  grid-column-start: 1;
  grid-column-end: span 1;
  grid-row-start: 4;
  grid-row-end: span 2;
}
.item5 div {
  height: 160px;
}
.item6 {
  grid-column-start: 2;
  grid-column-end: span 1;
  grid-row-start: 5;
  grid-row-end: span 2;
}
.item6 div {
  height: 520px;
}
.item7 {
  grid-column-start: 1;
  grid-column-end: span 1;
  grid-row-start: 6;
  grid-row-end: span 1;
}
.item7 div {
  height: 300px;
}
<main>
  <article class="item1"><div></div></article>
  <article class="item2"><div></div></article>
  <article class="item3"><div></div></article>
  <article class="item4"><div></div></article>
  <article class="item5"><div></div></article>
  <article class="item6"><div></div></article>
  <article class="item7"><div></div></article>
</main>

在这里你可以看到额外的红色间隙。包含的div上的高度只是为了模拟文章的真实内容,所以在真实例子中不能修改(在真实代码中保持默认)。根据编辑前的答案,我尝试了grid-auto-rows 属性,但没有解决问题。

显然这不是同一个问题(在 中)

问题是你指定了列的 height 强制它不填充剩余的并弄乱了 grid ,因为你指定它应该在哪里 startendgrid-columngrid-row 中,将右栏项目的 height 设置为 auto 将解决您的问题,

我相信 grid 表现如此的原因是因为您没有为 grid 设置 grid-template-rows ,行具有其内容的高度在第一列,

我认为你不应该设置 grid-items 的高度并使用 grid-template-rows ,如果你对 height:auto 的高度不满意,也许你应该考虑修改你的grid-row-startgrid-row-end

我希望这能解决您的问题,或者至少让您了解如何解决它。

main {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}
article {
  display: flex;
  background: red;
}
.item1 {
  height: 30px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 1;
  grid-row-end: 2;
}
.item2 {
  height: 100px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 2;
  grid-row-end: 3;
}
.item3 {
  height: 300px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 3;
  grid-row-end: 4;
}
.item4 {
  height: auto;
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 5;
}
.item5 {
  height: 160px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 4;
  grid-row-end: 6;
}
.item6 {
  height: auto;
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 5;
  grid-row-end: 7;
}
.item7 {
  height: 300px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 6;
  grid-row-end: 7;
}
<main>
  <article class="item1"></article>
  <article class="item2"></article>
  <article class="item3"></article>
  <article class="item4"></article>
  <article class="item5"></article>
  <article class="item6"></article>
  <article class="item7"></article>
</main>

您有一个包含三个显式列和 10 像素间距的网格容器:

main {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}

没有定义行。所有行都是隐式的并采用内容高度(因为网格容器的默认设置是 grid-auto-rows: auto)。

此容器内有七个使用 line-based placement.

定位的网格项

让我们将其分解为各个部分。


项目 1

.item1 {
    height: 30px;
    grid-column-start: 1;
    grid-column-end: 2;
    grid-row-start: 1;
    grid-row-end: 2;
}

很简单。项目 1 横跨第一列和第一行。高度为30px,设置行高。


项目 2

.item2 {
    height: 100px;
    grid-column-start: 1;
    grid-column-end: 2;
    grid-row-start: 2;
    grid-row-end: 3;
}

同样,非常简单。项目 2 横跨第一列和第二行。高度为100px,设置行高。


项目 3

.item3 {
    height: 300px;
    grid-column-start: 1;
    grid-column-end: 2;
    grid-row-start: 3;
    grid-row-end: 4;
}

与上面的两项一样,第 3 项简单明了。它跨越第一列和第三行。高度为300px,设置行高。

现在开始有点棘手了...


项目 4

.item4 {
    height: 490px;
    grid-column-start: 2;
    grid-column-end: 3;
    grid-row-start: 1;
    grid-row-end: 5;
}

项目 4 设置为总共四行:

grid-row-start: 1 / grid-row-end: 5

它的高度为 490px。

但项目 1、2 和 3 设置为跨越总共 行:

grid-row-start: 1 / grid-row-end: 4

...他们的总高度是:430px (30px + 100px + 300px)

因此,项目 4 创建了一个高度为 30px 的新行(490px - 430px - 30px 网格行间隙)。


项目 5

.item5 {
    height: 160px;
    grid-column-start: 1;
    grid-column-end: 2;
    grid-row-start: 4;
    grid-row-end: 6;
}

项目 5 的高度为 160 像素,设置为跨越两行。它从第四行(由项目 4 创建)开始并创建新的第五行。

因为行高设置为 auto,每行接收网格项目高度的相等分布,对于覆盖多个轨道的网格区域 defined in the spec。这使得第 4 行和第 5 行各 80 像素高。

重要提示:注意项目 5 等高行如何扩展第 4 行,该行现在与项目 4 底部的原始位置间隔开。第一个缺口已创建。


项目 6

.item6 {
    height: 520px;
    grid-column-start: 2;
    grid-column-end: 3;
    grid-row-start: 5;
    grid-row-end: 7;
}

项目 6 设置为从第 5 行开始。如上所述(请参阅重要),第 5 行不能再适合项目 4,因为 grid-auto-rows: auto在项目 5 网格区域。 这导致项目 6 上方有 50 像素的间隙。

80px height of row 4 - 30px excess of Item 4 = 50px

但现在项目 6 添加到项目 5 创建的第 5 行的 80px 高度。第二个间隙已创建。


项目 7

.item7 {
    height: 300px;
    grid-column-start: 1;
    grid-column-end: 2;
    grid-row-start: 6;
    grid-row-end: 7;
}

最后两行的高度由以下三个因素决定:

  • 项目 5 的高度,第 5 行为 80px
  • 项目6的高度,520px,与第5行的高度相结合,跨越两行
  • 项目 7 的高度,300 像素,跨越 1 行

出于同样的原因,网格行 5 与项目 4 间隔开,网格行 6 与项目 5 间隔开: auto 行高将项目 6 的高度分配到它所覆盖的行中。


一个解决方案

考虑将 grid-auto-rows 设置为 10px 之类的值,而不是将高度设置为网格项。然后使用span关键字创建你想要的网格区域。

所以不是这个...

main {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}

.item5 {
  height: 160px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 4;
  grid-row-end: 6;
}

考虑一下:

main {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 10px; /* new */
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}

.item5 {
  /* height: 160px; */
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 4;     /* this would have to be adjusted, as well */
  grid-row-end: span 16; /* new */
}

这里介绍了这种方法:CSS-only masonry layout but with elements ordered horizontally

差距来自错误计算高度你正在设置容器。您应该注意元素元素跨越的 10px 间距。

为了保持流畅,您可以使用 min-height 而不是 height 并使用 grid-template-rowsgrid-auto-rows 以某种方式为行设置 min-height

您也可以完全不设置高度,让框和行根据它们所容纳的内容调整大小。

使用 min-heightgrid-template-rows 进行测试(grid-auto-rows,请参阅其他答案)

main {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows:repeat(auto-fill, 4em);/* min-height of 4em if row is empty*/
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}
article {
  display: flex;
  background: red;
}
.item1 {
  /* it will be at least 4em of height*/
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 1;
  grid-row-end: 2;
}
.item2 {
  min-height:180px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 2;
  grid-row-end: 3;
}
.item3 {
  min-height:80px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 3;
  grid-row-end: 4;
}
.item4 {
  min-height:150px;
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 5;
}
.item5 {
  min-height:450px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 4;
  grid-row-end: 6;
}
.item6 {
 min-height:240px;
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 5;
  grid-row-end: 7;
}
.item7 {
  min-height:160px;
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 6;
  grid-row-end: 7;
}
/* see and name me */
article:before{
  content:attr(class);
  font-size:2em;
}
<main>
  <article class="item1"></article>
  <article class="item2"></article>
  <article class="item3"></article>
  <article class="item4"></article>
  <article class="item5"></article>
  <article class="item6"></article>
  <article class="item7"></article>
</main>

或者不设置任何高度,让布局从内容中增长:

main {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
   grid-column-gap: 10px;
  grid-row-gap: 10px;
}
article {
  display: flex;
  background: red;
  /* to deal with 'lorem ipsum' content added  */
  flex-flow:column;
  padding:0.5em;
}
.item1 {
  /* it will be at least 4em of height*/
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 1;
  grid-row-end: 2;
}
.item2 {
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 2;
  grid-row-end: 3;
}
.item3 {
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 3;
  grid-row-end: 4;
}
.item4 {
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 5;
}
.item5 {
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 4;
  grid-row-end: 6;
}
.item6 {
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 5;
  grid-row-end: 7;
}
.item7 {
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 6;
  grid-row-end: 7;
}
<main>
  <article class="item1"><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p></article>
  <article class="item2"><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p></article>
  <article class="item3"><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.</p></article>
  <article class="item4"><h1>HTML Ipsum Presents</h1>

<p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. <a href="#">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p>

<h2>Header Level 2</h2>

<ol>
   <li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
   <li>Aliquam tincidunt mauris eu risus.</li>
</ol>
</article>
  <article class="item5"><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus</p></article>
  <article class="item6"><p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo.</p></article>
  <article class="item7"></article>
</main>