为什么 grid-gap 会更改 CSS 网格中的列宽?

Why does grid-gap change a column's width in CSS Grid?

使用 css-grid 我在容器内设置了一个 24 列的网格,宽度为 1002 像素。

在容器 div 内,有一个 child div 跨越 21 列。我期望 child div 的宽度是:

21/24 * 1002 = 876.75

当添加grid-gap 属性时,列的宽度减小到873px,这是不希望的。

如何编写 CSS 以便 div 的宽度为 876.75px?

参见示例: https://codepen.io/edtalmadge/pen/MvLrqW?editors=1100

HTML

<div class="container1">
  <div class="column">
    <p>No grid-gap ...width is 876px as expected</p>
  </div>
</div>

<div class="container2">
  <div class="column">
    <p>grid-gap: 30px; ...width becomes 873px (3px too narrow)</p>
  </div>
</div>

CSS

   /* no grid gap */
   .container1 {
      display: grid;
      grid-template-columns: repeat(24, 1fr);
      width: 1002px;
      background-color: #ededed;
    }

    /* has grid gap */
    .container2 {
      grid-gap: 30px; // This causes the width of .column to increase
      display: grid;
      grid-template-columns: repeat(24, 1fr);
      width: 1002px;
      background-color: #ededed;
    }

    .column {
      grid-column: span 21;
      background-color: gray;
    }

.container1 {
  display: grid;
  grid-template-columns: repeat(24, 1fr);
  width: 1002px;
  background-color: #ededed;
}

.container2 {
  display: grid;
  grid-template-columns: repeat(24, 1fr);
  width: 1002px;
  background-color: #ededed;
  grid-gap: 30px;
  border-top: 1px solid yellow;
}

.column {
  grid-column: span 21;
  background-color: gray;
}

p {
  text-align: center;
  color: #fff;
  font-family: Helvetica, Arial, sans-serif;
}
<div class="container1">
  <div class="column">
    <p>No grid-gap ...width is <strong style="color: lime;">876px</strong> as expected</p>
  </div>
</div>

<div class="container2">
  <div class="column">
    <p>grid-gap: 30px; ...width becomes <strong style="color: #fb665e;">873px</strong> (3px too narrow)</p>
  </div>
</div>

两个网格容器都有 24 列和 1002 像素的宽度:

grid-template-columns: repeat(24, 1fr);
width: 1002px

您的问题只涉及前21列:

.column {
   grid-column: span 21;
}

这意味着最后三列和网格间隙应从您的计算中排除。

Using Firefox's grid overlay tool。条纹条是排水沟。


第一个容器

在第一个容器中,没有间距,每个 fr 单位等于 41.75px。

1002 / 24 = 41.75

这意味着 21 列等于 876.75 像素的宽度。

41.75 * 21 = 876.75px

第二个容器

关于第二个容器,首先要记住的是fr单位只代表免费space。这是在考虑了其他尺寸后剩下的 space,包括排水沟

7.2.3. Flexible Lengths: the fr unit

A flexible length or <flex> is a dimension with the fr unit, which represents a fraction of the free space in the grid container.

free space

Equal to the available grid space minus the sum of the base sizes of all the grid tracks (including gutters), floored at zero. If available grid space is indefinite, the free space is indefinite as well.

在第一个容器中,所有 space 都是免费的 space。在第二个容器中不是这样。

同样重要的是要注意:grid-gap 属性 仅适用于网格项之间,而不适用于项和容器之间。

10.1. Gutters: the grid-column-gap, grid-row-gap, and grid-gap properties

These properties specify the gutters between grid rows and grid columns, respectively.

因此,在 24 列的网格中有 23 个间距(见上图)。

所以对于第二个容器,我们必须先减去排水沟占用的space:

1002 - (30 * 23) = 312

我们现在知道第二个容器中空闲的space是312px。

现在我们需要确定每个 fr 单位的价值。

312 / 24 = 13

所以每个fr单位等于13px。

现在我们需要计算出 21 列的间距和 fr 的总宽度:

21 * 13 = 273px (total width of free space)
20 * 30 = 600px (total width of gutters)
          -----
          873px

或者您可以从总宽度中减去三个 fr 个单位和三个间距:

1002px - (13 * 3) - (30 * 3) = 873px

解决方案

由于您使用 fr 单位来确定长度,并且容器之间的空闲量 space 不同,您的代码只能在全宽 (24列)。

要在小于全宽的情况下实现等宽,您需要对列使用不同的大小调整方法,例如 pxem

根据您的总体目标,可能还有其他解决方案。