edt
edt

Reputation: 22410

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

Using css-grid I have setup a 24 column grid inside of container that is 1002px wide.

Inside the container div, there is a child div that spans 21 columns. The width of I am expecting of the child div is:

21/24 * 1002 = 876.75

When a grid-gap property is added, the width of the column decreases to 873px, which is not desired.

How can I write my CSS so that the width of the div is 876.75px?

See example: 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>

Upvotes: 8

Views: 10815

Answers (1)

Michael Benjamin
Michael Benjamin

Reputation: 371113

Both grid containers have 24 columns and a width of 1002px:

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

Your question involves only the first 21 columns:

.column {
   grid-column: span 21;
}

This means that the last three columns and grid gaps should be excluded from your calculations.

enter image description here

Using Firefox's grid overlay tool. The striped bars are the gutters.


First Container

In the first container, having no gutters, each fr unit is equal to 41.75px.

1002 / 24 = 41.75

This means that 21 columns equal a width of 876.75px.

41.75 * 21 = 876.75px

Second Container

With regard to the second container, the first thing to remember is that the fr unit represents only free space. That is the space left over after other sizes have been factored in, including the gutters.

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.

In the first container, all space is free space. Not so in the second container.

Also important to note: The grid-gap property applies only between grid items, and never between items and the container.

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.

Therefore, in a 24-column grid there are 23 gutters (see image above).

So for the second container we must first subtract the space taken by the gutters:

1002 - (30 * 23) = 312

We now know that the free space in the second container is 312px.

Now we need to determine the value of each fr unit.

312 / 24 = 13

So each fr unit is equal to 13px.

Now we need to figure out the total width of the gutters and fr's for 21 columns:

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

Or you can just subtract three fr units and three gutters from the total width:

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

Solution

Since you're using the fr unit for establishing length, and the amount of free space differs between containers, your code can achieve equal width for both containers only at full width (24 columns).

To achieve equal width at less than full width, you'll need to use a different sizing method, such as px or em, for the columns.

There may be other solutions depending on your overall goal.

Upvotes: 9

Related Questions