5

I'd like to have a grid like this:

.grid{
  display:grid;
grid-gap:50%;
  background-color:blue;
}
.grid-1{
  background-color:red;
}
<div class="grid">
 <div class="grid-1">
  test
 </div>
 <div class="grid-1">
  test
 </div>
 <div class="grid-1">
  test
 </div>
</div>

I think it's a really big problem beacuse all browser doesn't correctly understand percentage values.

How to resolve this?

Temani Afif
  • 245,468
  • 26
  • 309
  • 415

1 Answers1

11

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?

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • 1
    Thanks for you answer I have two points 1. 50% Grid-gap means 50% from the sum of the rows heights and the columns width After that the total height Could be easily calculatet 2. I hate px values because they are Not responsive. Any posibility to resolute this? – Markus Schneider Dec 01 '18 at 20:41
  • @MarkusSchneider no, you have a cycle, it seems easy to you but it's not : Imagine you have an element A with a height defined by the element B and the element B has a height defined in percentage of the height A. This is the case here, the grid is A and the gap is B. We first define the height of A and then B if we get back to redefine A we are then obliged to redefine B and so on. It never ends ... And as I said you need to ask your self "percentage of what?" even *you* you cannot answer this question. Can you tell me % of what? – Temani Afif Dec 01 '18 at 20:48
  • I would calculate it that way: height row 1+ height row 2 + height row 3 + 0,5*(3-1)*(height row 1+ height row 2 + height row 3) = grid height. So for me actual it calculates row heights, than grid than gap, i would calculate row heights, gap, grid – Markus Schneider Dec 01 '18 at 20:55
  • @MarkusSchneider you want the calculation to be like that :) you think it should be like that but not. The calculation is as follow: (1) we cannot resolve grid gap because its percenage, we move (2) we calculate the height of grid (in this case it the sum of the 3 row but it can be something else depending on other properties) (3) now we have the height of our grid we can resolve the grid gap (4) we add the grid gap (5) we have the overflow and we stop. This case seems easy but check the links I shared to see other situation where it's more complex – Temani Afif Dec 01 '18 at 21:21
  • @MarkusSchneider don't forget that we can have margin, padding, etc and it's not trivial for the browser to do the calculation you want. Grid gap is also a part of the grid height. You can clearly notice this when using pixel value so the grid height is not only the row but also the gap, margin, padding, etc. – Temani Afif Dec 01 '18 at 21:22
  • So is there any possible fully responsive solution for the problem? – Markus Schneider Dec 01 '18 at 22:08
  • @MarkusSchneider it depend how you want it to be responsive, there is plenty of ways. As a side not we talk about responsive when it comes to change the width of element and not height. height is never an issue for responsiveness – Temani Afif Dec 01 '18 at 22:10
  • The best solution would be my solution but the div resizing correct. My Problem ist I have 5 columns in full screen and 3 for mobile. on full screen (1920x1080) 50px are no problem. on 1366x768 it could be a problem and for tablets and mobile phones there are so much different types so define it in px is no solution. The height to be responsive is a problem wenn rotating a screen (e.g. mobile phone or tablet) – Markus Schneider Dec 01 '18 at 22:15
  • @MarkusSchneider can you share code? with column you won't have issue like with rows – Temani Afif Dec 01 '18 at 22:19
  • The css for the grid is:.grid { margin-left: 20%; margin-right: 20%; display: grid; grid-template-columns: 1fr 1fr 1fr 1fr 1fr; grid-gap: 2%; text-align: center; background: #f7f7f7; padding: 20px 5%; padding-top: 0px; }. The widht of the div is exact 60% and all columns are sized correct (including the gap). So I don't unterstand it.... Columns work - rows don't work – Markus Schneider Dec 01 '18 at 22:32
  • @MarkusSchneider with column we don't have an issue because the width is not defined by the content like height, so there is no cycle .. the width is 100% of the parent width so we can resolve the gap ... if your grid is your only element then it will have the width of the browser and then we 2% from this width – Temani Afif Dec 01 '18 at 22:41
  • So my css would be: grid-gap:10px 2%; /* Please css learn calculating the height of a div */ – Markus Schneider Dec 01 '18 at 22:53
  • @MarkusSchneider yes this will make it responsive in width and height will be calculated fine ;) – Temani Afif Dec 01 '18 at 22:54