6

I have a CSS grid of "cards" that can have some optional content in the middle. Within the cards I'm using grid-template-rows: subgrid so that the rows of content in each card can align with other cards. I'm using a row-gap: 50px to space the cards apart from each other but then I use row-gap: 0 in the card because I don't want to inherit the gap within the card.

The problem is I now have a space in the middle of each card that I can't seem to collapse. It is always tied to the parent grid's row-gap. Can someone explain what I'm missing?

Remove marked spaces

Reproduced below or here: https://codesandbox.io/p/sandbox/jft9cp

.grid {
  display: grid;
  grid-template-columns: 150px 150px 150px;
  grid-auto-rows: min-content;
  column-gap: 15px;
  row-gap: 50px;
}
.card {
  border: 1px solid black;
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 3;
  row-gap: 0;
}
.topRow {
  grid-row: 1;
}
.middleRow {
  grid-row: 2;
}
.bottomRow {
  grid-row: 3;
}
body {
  font-size: 26px;
}
  <div class="grid">
    <div class="card">
      <div class="topRow">Top Row</div>
      <div class="middleRow">Middle Row</div>
      <div class="bottomRow">Bottom Row</div>
    </div>
    <div class="card">
      <div class="topRow">Top Row</div>
      <div class="middleRow">Optional</div>
      <div class="bottomRow">Bottom Row</div>
    </div>
    <div class="card">
      <div class="topRow">Top Row</div>
      <div class="bottomRow">Bottom Row</div>
    </div>
    <div class="card">
      <div class="topRow">Top Row</div>
      <div class="bottomRow">Bottom Row</div>
    </div>
    <div class="card">
      <div class="topRow">Top Row</div>
      <div class="bottomRow">Bottom Row</div>
    </div>
    <div class="card">
      <div class="topRow">Top Row</div>
      <div class="bottomRow">Bottom Row</div>
    </div>
  </div>

0

2 Answers 2

2

You are not inheriting the gap but it's still there on the main grid and since you are spanning 3 rows, you will have at least 2 gaps so a minimum of 100px of height.

Here is your code with empty divs. You will notice a height equal to 102px (2 gaps + border).

.grid {
  display: grid;
  grid-template-columns: 150px 150px 150px;
  grid-auto-rows: min-content;
  column-gap: 15px;
  row-gap: 50px;
}

.card {
  border: 1px solid black;
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 3;
  row-gap: 0;
}

.topRow {
  grid-row: 1;
}

.middleRow {
  grid-row: 2;
}

.bottomRow {
  grid-row: 3;
}

body {
  font-size: 26px;
}
<div class="grid">
  <div class="card">
    <div class="topRow"> </div>
    <div class="middleRow"> </div>
    <div class="bottomRow"> </div>
  </div>
  <div class="card">
    <div class="topRow"> </div>
    <div class="middleRow"> </div>
    <div class="bottomRow"> </div>
  </div>
  <div class="card">
    <div class="topRow"> </div>
    <div class="middleRow"> </div>
    <div class="bottomRow"> </div>
  </div>
  <div class="card">
    <div class="topRow"> </div>
    <div class="middleRow"> </div>
    <div class="bottomRow"> </div>
  </div>
  <div class="card">
    <div class="topRow"> </div>
    <div class="middleRow"> </div>
    <div class="bottomRow"> </div>
  </div>
  <div class="card">
    <div class="topRow"> </div>
    <div class="middleRow"> </div>
    <div class="bottomRow"> </div>
  </div>
</div>

Instead of using gap, consider an empty row with 50px of height

.grid {
  display: grid;
  grid-template-columns: 150px 150px 150px;
  grid-auto-rows: auto auto auto 50px; /* 3 rows + gap */
  column-gap: 15px;
  margin-bottom: -50px; /* the hacky part of the solution to avoid the space of the last row */
} 
.card {
  border: 1px solid black;
  display: grid;
  grid-template-rows: subgrid;
  grid-row: span 4; /* span 4 rows */
  margin-bottom: 50px; /* to consume the fourth row as margin */
}
.bottomRow {
  grid-row: 3; /* defining the bottom row is enough */
}


body {
  font-size: 26px;
}
<div class="grid">
    <div class="card">
      <div class="topRow">Top Row</div>
      <div class="middleRow">Middle Row</div>
      <div class="bottomRow">Bottom Row</div>
    </div>
    <div class="card">
      <div class="topRow">Top Row</div>
      <div class="middleRow">Optional</div>
      <div class="bottomRow">Bottom Row</div>
    </div>
    <div class="card">
      <div class="topRow">Top Row</div>
      <div class="bottomRow">Bottom Row</div>
    </div>
    <div class="card">
      <div class="topRow">Top Row</div>
      <div class="bottomRow">Bottom Row</div>
    </div>
    <div class="card">
      <div class="topRow">Top Row</div>
      <div class="bottomRow">Bottom Row</div>
    </div>
    <div class="card">
      <div class="topRow">Top Row</div>
      <div class="bottomRow">Bottom Row</div>
    </div>
  </div>
  
  Some content after

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for clear explanation. I'm sad the solution to row-gap is to not use row-gap but I guess nothing is perfect. I'll either use your extra grid row or maybe just some margins. Either way, nice answer.
0

To remove the unwanted space, you need to decouple the .card's internal layout from the parent's row-gap or adjust the grid structure.

Instead of relying on subgrid, define the .card's internal rows explicitly and control the gaps within it. Remove grid-template-rows: subgrid and use a standard grid with your own row definitions.

.grid {
  display: grid;
  grid-template-columns: 150px 150px 150px;
  grid-auto-rows: min-content;
  column-gap: 15px;
  row-gap: 50px;
}
.card {
  border: 1px solid black;
  display: grid;
  grid-template-rows: auto auto auto; /* Explicit rows */
  row-gap: 0; /* No internal gap */
}
.topRow {
  grid-row: 1;
}
.middleRow {
  grid-row: 2;
}
.bottomRow {
  grid-row: 3;
}
body {
  font-size: 26px;
}
 <div class="grid">
    <div class="card">
      <div class="topRow">Top Row</div>
      <div class="middleRow">Middle Row</div>
      <div class="bottomRow">Bottom Row</div>
    </div>
    <div class="card">
      <div class="topRow">Top Row</div>
      <div class="middleRow">Optional</div>
      <div class="bottomRow">Bottom Row</div>
    </div>
    <div class="card">
      <div class="topRow">Top Row</div>
      <div class="bottomRow">Bottom Row</div>
    </div>
    <div class="card">
      <div class="topRow">Top Row</div>
      <div class="bottomRow">Bottom Row</div>
    </div>
    <div class="card">
      <div class="topRow">Top Row</div>
      <div class="bottomRow">Bottom Row</div>
    </div>
    <div class="card">
      <div class="topRow">Top Row</div>
      <div class="bottomRow">Bottom Row</div>
    </div>
  </div>

1 Comment

notice how the bottom row of the third item is not aligned with the others, that's why subgrid is needed

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.