【问题标题】:Why does CSS Grid layout add extra gaps between cells?为什么 CSS Grid 布局会在单元格之间添加额外的间隙?
【发布时间】:2018-03-18 21:11:22
【问题描述】:

无法弄清楚为什么 CSS 网格布局会在垂直单元格周围的内容中添加不需要的额外空间,尽管边距和填充被清零:

.grid {
  display: grid;
  grid-template-columns: 13fr 11fr 4fr 20fr;
  grid-auto-rows: 12fr;
  grid-gap: 4px;
  align-items: center;
}

.grid figure {
  outline: 1px solid red;
  margin: 0;
  padding: 0;
}

.grid figure img {
  margin: 0;
  padding: 0;
  width: 100%;
  display: block;
}

.grid .gi13x12 {
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 1;
  grid-row-end: 13;
}

.grid .gi11x6.one {
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 7;
}

.grid .gi11x6.two {
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 7;
  grid-row-end: 13;
}

.grid .gi4x4.one {
  grid-column-start: 3;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 5;
}

.grid .gi4x4.two {
  grid-column-start: 3;
  grid-column-end: 4;
  grid-row-start: 5;
  grid-row-end: 9;
}

.grid .gi4x4.three {
  grid-column-start: 3;
  grid-column-end: 4;
  grid-row-start: 9;
  grid-row-end: 13;
}

.grid .gi20x12 {
  grid-column-start: 4;
  grid-column-end: 5;
  grid-row-start: 1;
  grid-row-end: 13;
}
<div class="grid">
  <figure class="gi13x12">
    <img itemprop="image" src="http://placehold.it/130x123">
  </figure>
  <figure class="gi11x6 one">
    <img itemprop="image" src="http://placehold.it/110x60">
  </figure>
  <figure class="gi11x6 two">
    <img itemprop="image" src="http://placehold.it/110x60">
  </figure>
  <figure class="gi4x4 one">
    <img itemprop="image" src="http://placehold.it/40x39">
  </figure>
  <figure class="gi4x4 two">
    <img itemprop="image" src="http://placehold.it/40x39">
  </figure>
  <figure class="gi4x4 three">
    <img itemprop="image" src="http://placehold.it/40x39">
  </figure>
  <figure class="gi20x12">
    <img itemprop="image" src="http://placehold.it/200x120">
  </figure>
</div>

https://jsfiddle.net/adanchenkov/dy77hk9k/

【问题讨论】:

  • 该空间与 CSS Grid、margin 或 padding 无关,它来自于 img 是一个内联元素,它像字符一样有一个空格,用于下降,在基线。
  • @LGSon,在这种情况下,我不相信后裔是问题。
  • @Michael_B 我回答后问题已更新。如果您检查问题中的代码是如何呈现的,您就会明白为什么我都这么评论和回答了。添加的屏幕转储显示的小提琴呈现不同的结果。尽管如此,我的回答确实解决了这两个问题,尽管你的回答更正确。所以我 +1 :)
  • @Michael_B 感谢您的评论,我在回答中添加了注释

标签: html css css-grid


【解决方案1】:

垂直间隙是由图像未填充网格项中的垂直空间引起的。

在容器上使用align-items: center 会使问题变得更糟,这会删除align-items: stretch 默认值。

基本上,网格项之间没有间隙。它们形成一个干净、排列整齐的网格。但是因为图片比包含它们的项目小,然后项目以align-items垂直居中,所以有很多差距。

这里有更详细的解释,使用火狐的网格叠加工具进行说明:

(1) 这是您的网格grid-row-gapgrid-column-gap 为 0 时

红线代表网格项目。图像是网格项目的内容。虚线表示网格线。


(2)没有问题grid-column-gap为10px时


(3) 但是看看会发生什么grid-row-gap 是 10px 时

网格项目(红线)整齐地包裹着它们的内容(图像)。这只是因为容器设置为align-items: center


(4) 现在让我们删除align-items: center(恢复默认的stretch值)并保留grid-column-gap: 10pxgrid-row-gap: 10px

如您所见,网格项目(具有红色边框和黄色背景)现在扩展了整个高度。但是图像比物品小,会留下空隙。


(5) 这是上面 (4) 中没有指标的网格。

align-items: stretch

align-items: center(与问题中的布局相同)


(6) 所以关键是让图像填充网格项。

一个简单的解决方案是将display: flex 应用于网格项目,这会自动将align-items: stretch 分配给图像,使它们占据整个高度。

然后,根据您希望图像的外观,您可以使用object-fit 来管理它们的外观。

将此添加到您的代码中:

.grid figure {
   display: flex;
}

.grid figure img {
   object-fit: cover; /* also try `contain` and `fill` */
}

通过上面的调整,网格呈现如下:

revised fiddle

.grid {
  display: grid;
  grid-template-columns: 13fr 11fr 4fr 20fr;
  grid-auto-rows: repeat(12, 1fr);
  grid-gap: 10px;
  /* align-items: center; */
}
.grid figure {
  border: 2px solid red;
  margin: 0;
  padding: 0;
  background-color: yellow;
  display: flex; /* new */
}
.grid figure img {
  margin: 0;
  padding: 0;
  width: 100%;
  display: block;
  object-fit: cover; /* new */
}
.grid .gi13x12 {
  grid-column-start: 1;
  grid-column-end: 2;
  grid-row-start: 1;
  grid-row-end: 13;
}
.grid .gi11x6.one {
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 7;
}
.grid .gi11x6.two {
  grid-column-start: 2;
  grid-column-end: 3;
  grid-row-start: 7;
  grid-row-end: 13;
}
.grid .gi4x4.one {
  grid-column-start: 3;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 5;
}
.grid .gi4x4.two {
  grid-column-start: 3;
  grid-column-end: 4;
  grid-row-start: 5;
  grid-row-end: 9;
}
.grid .gi4x4.three {
  grid-column-start: 3;
  grid-column-end: 4;
  grid-row-start: 9;
  grid-row-end: 13;
}
.grid .gi20x12 {
  grid-column-start: 4;
  grid-column-end: 5;
  grid-row-start: 1;
  grid-row-end: 13;
}

* { box-sizing: border-box; }
<div class="grid">
	<figure class="gi13x12">
		<img itemprop="image" src="http://placehold.it/130x123">
	</figure>
	<figure class="gi11x6 one">
		<img itemprop="image" src="http://placehold.it/110x60">
	</figure>
	<figure class="gi11x6 two">
		<img itemprop="image" src="http://placehold.it/110x60">
	</figure>
	<figure class="gi4x4 one">
		<img itemprop="image" src="http://placehold.it/40x39">
	</figure>
	<figure class="gi4x4 two">
		<img itemprop="image" src="http://placehold.it/40x39">
	</figure>
	<figure class="gi4x4 three">
		<img itemprop="image" src="http://placehold.it/40x39">
	</figure>
	<figure class="gi20x12">
		<img itemprop="image" src="http://placehold.it/200x120">
	</figure>
</div>

Firefox 中酷炫的网格叠加功能

在 Firefox 开发工具中,当您检查网格容器时,CSS 声明中有一个小网格图标。单击它会在页面上显示网格的轮廓。

更多详情:https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_grid_layouts

【讨论】:

    【解决方案2】:

    请注意,此答案在最新更新之前发布,因此,以不同方式回答初始代码示例(问题中的那个)。 Michael 出色地回答了问题的编辑版本。

    首先,内部空间与 CSS Grid、margin 或 padding 无关,它来自于 img 是一个内联元素,它像字符一样在基线下方有一个空格,用于下行。

    一种解决方案是将display: block 添加到.grid figure img 规则中。

    .grid figure img {
      display: block;
      width: 100%;
    }
    

    其次,外层空间是由grid-auto-rows引起的,所以把它从.grid规则中去掉。

    .grid {
      display: grid;
      grid-template-columns: 13fr 11fr 4fr 20fr;
      /*grid-auto-rows: 12fr;                      remove this  */
      grid-gap: 3px;
      align-items: flex-start;
    }
    

    堆栈sn-p

    .grid {
      display: grid;
      grid-template-columns: 13fr 11fr 4fr 20fr;
      /*grid-auto-rows: 12fr;                      removed  */
      grid-gap: 3px;
      align-items: flex-start;
    }
    .grid figure {
      outline: 1px solid red;
      margin: 0;
      padding: 0;
    }
    .grid figure img {
      width: 100%;
      display: block;
    }
    .grid .gi13x12 {
      grid-column-start: 1;
      grid-column-end: 2;
      grid-row-start: 1;
      grid-row-end: 13;
    }
    .grid .gi11x6.one {
      grid-column-start: 2;
      grid-column-end: 3;
      grid-row-start: 1;
      grid-row-end: 7;
    }
    .grid .gi11x6.two {
      grid-column-start: 2;
      grid-column-end: 3;
      grid-row-start: 7;
      grid-row-end: 13;
    }
    .grid .gi4x4.one {
      grid-column-start: 3;
      grid-column-end: 4;
      grid-row-start: 1;
      grid-row-end: 5;
    }
    .grid .gi4x4.two {
      grid-column-start: 3;
      grid-column-end: 4;
      grid-row-start: 5;
      grid-row-end: 9;
    }
    .grid .gi4x4.three {
      grid-column-start: 3;
      grid-column-end: 4;
      grid-row-start: 9;
      grid-row-end: 13;
    }
    .grid .gi20x12 {
      grid-column-start: 4;
      grid-column-end: 5;
      grid-row-start: 1;
      grid-row-end: 13;
    }
    <div class="grid">
    	<figure class="gi13x12">
    		<img itemprop="image" src="http://placehold.it/130x123">
    	</figure>
    	<figure class="gi11x6 one">
    		<img itemprop="image" src="http://placehold.it/110x60">
    	</figure>
    	<figure class="gi11x6 two">
    		<img itemprop="image" src="http://placehold.it/110x60">
    	</figure>
    	<figure class="gi4x4 one">
    		<img itemprop="image" src="http://placehold.it/40x39">
    	</figure>
    	<figure class="gi4x4 two">
    		<img itemprop="image" src="http://placehold.it/40x39">
    	</figure>
    	<figure class="gi4x4 three">
    		<img itemprop="image" src="http://placehold.it/40x39">
    	</figure>
    	<figure class="gi20x12">
    		<img itemprop="image" src="http://placehold.it/200x120">
    	</figure>
    </div>

    关于您的 Fiddle 示例(和添加的屏幕转储),其中不匹配内部代码示例,并且经过上述调整后,内部空间仍然很小,这是由于较小元素高度的总和造成的与最高的不匹配,它的图像也不匹配,因为最高的图像是 123px,但较小的图像是 120px (2*60) 和 117px (3*39)。

    【讨论】:

    • 谢谢你,很抱歉编辑小提琴链接。它确实与编辑的问题匹配,并且间隙值为 3 px,所有 4 列的高度应该相等:123px = 60px*2+3px = 39px*3+3px*2 = 123px。问题仍然存在:是什么导致第 2 列和第 3 列中垂直堆叠元素之间的间隙值大于设置的 3px?
    • @AlexeiDanchenkov 更新了我的答案,它是由grid-auto-rows ... jsfiddle.net/dy77hk9k/1引起的
    • grid-auto-rows 可能看起来多余,但它定义了 12 行,然后用于单个项目的 grid-row-start 和 grid-row-end。即使那样,我也看不到带间隙的较小图像如何占用更大的高度?
    • @AlexeiDanchenkov 由于您没有超出定义网格范围的任何元素,这就是grid-auto-rows 的用途,您打算如何定位应该的行(通过grid-template-rows)超出范围?
    • 你是对的。 grid-template-rows: repeat(12, 1fr); 应该包括在内。它不会改变间距问题。
    【解决方案3】:

    在单元格放置“ grid-gap: 0px;”后删除间隙到 .grid css 类

    【讨论】:

      【解决方案4】:

      您可以通过使图像浮动来删除图形内部的空间。

      .grid figure img {
          margin: 0;
          padding: 0;
          width: 100%;
         float: left;
      }
      

      请查找更新代码here

      【讨论】:

      • 浮动(除了在网格布局中是一只奇怪的野兽)不适用于非零网格间隙。我确实想保持 3px 的网格间隙(应该按照规范工作)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-13
      • 2016-09-30
      • 1970-01-01
      • 2022-08-03
      相关资源
      最近更新 更多