Why percentage value within grid-gap create overflow in CSS grid?

Solution 1:

Initially, we cannot resolve the percentage of the grid-gap since it depends on the height so we ignore it (we consider it as auto). The browser is first calculating the height considering content like this:

console.log(document.querySelector('.grid').offsetHeight)
.grid {
  display: grid;
  background-color: blue;
}

.grid-1 {
  background-color: red;
  opacity:0.5;
}
<div class="grid">
  <div class="grid-1">
    test
  </div>
  <div class="grid-1">
    test
  </div>
  <div class="grid-1">
    test
  </div>
</div>

This height is used as reference to calculate the gap then we added it to the height (the one we used to find the gap that is based on the content). This will not trigger the height calculation of the grid again because it will create a cycle and will have an infinite loop thus the browser will stop here and we will have an overflow.

console.log(document.querySelector('.grid').offsetHeight)

console.log(document.querySelector('.grid-1:nth-child(2)').offsetTop - document.querySelector('.grid-1:nth-child(1)').offsetTop - document.querySelector('.grid-1:nth-child(1)').offsetHeight)
.grid {
  display: grid;
  grid-gap:100%;
  background-color: blue;
  margin-top:50px;
}

.grid-1 {
  background-color: red;
  opacity:0.5;
  transform:translateY(-100%);
}
<div class="grid">
  <div class="grid-1">
    test
  </div>
  <div class="grid-1">
    test
  </div>
  <div class="grid-1">
    test
  </div>
</div>

As you can see, I used 100% and added some transfomation to see that the gap is equal to the initial height (the JS code also confirm this).

A trivial fix is to avoid percentage values and use pixel values so that the browser will include them in the initial calculation. In all the cases, using percentage value isn't good is such situation as you don't know "percentage of what?"

.grid {
  display: grid;
  grid-gap:50px;
  background-color: blue;
  margin-top:50px;
}

.grid-1 {
  background-color: red;
  opacity:0.5;
}
<div class="grid">
  <div class="grid-1">
    test
  </div>
  <div class="grid-1">
    test
  </div>
  <div class="grid-1">
    test
  </div>
</div>

You can refer to the official specification to get more details about this behavior but it won't be trivial to follow:

https://www.w3.org/TR/css-sizing-3/#percentage-sizing


Here is more examples where percentage values are evaluated later and create unwanted results:

Why is my Grid element's height not being calculated correctly?

CSS Grid - unnecessary word break

Why does percentage padding break my flex item?