CSS Grid, empty row still adds gap
Asked Answered
A

1

7

I have a CSS grid, sometimes not all the elements are used. In the actual use case I am using the grid for input widgets, where there maybe extra help text or errors dropped into a specific grid-area. The problem I have is with grid-gap, if the row is empty, it still applies the gap. This results in a double row gap at bottom. Is there a way to disable showing gaps between empty rows?

I face this problem all the time, it makes grid gap unusable to me, so generally I don't use grid-gap, and use more complicated margin setups.

.parent {
  background: gray;
  padding: 16px;
  margin: 16px;
  display: grid;
  grid-template-columns: 64px 128px;
  grid-template-areas:
"childa childb"
"childc childd"
"childe childf";
  grid-gap: 16px;
}

[class^="child"] {
  background-color: red;   
}

.childa { grid-area: childa }
.childb { grid-area: childb }
.childc { grid-area: childc }
.childd { grid-area: childd }
.childe { grid-area: childe }
.childf { grid-area: childf }
<p>Grid gap is okay if all cells filled:</p>
<div class="parent">
  <span class="childa">cell A</span>
  <span class="childc">cell C</span>
  <span class="childb">cell B</span>
  <span class="childe">cell E</span>
  <span class="childf">cell F</span>
  <span class="childd">cell D</span>
</div>
<p>Note the double gap at the bottom due to the empty row:</p>
<div class="parent">
  <span class="childa">cell A</span>
  <span class="childb">cell B</span>
  <span class="childd">cell D</span>
</div>
Angelikaangelina answered 19/1, 2022 at 19:33 Comment(10)
"Is there a way to semantically disable showing gaps between empty rows?"- - No, there is notAnaanabaena
@Paulie_D, okay dropped the word "semantically". was just trying to convey, 'none hacky'Angelikaangelina
why are you adding areas since you have the default flow? only specify 2 columns and it's done, the browser will do the job for youLucylud
The problem is that having defined a grid area/row it's gonna have a gap applied. If you can dispense with those and just use the natural flow the problem goes away - codepen.io/Paulie-D/pen/poWmdvOAnaanabaena
@TemaniAfif Because the order of which html items are added is given, e.g. the input, its label, its prefix, its errors, its help text, etc, is not always in the same order. and the grid-template-areas definition changes depending on media querries.Angelikaangelina
you still can do without areas. Share with us a real use case if you want to get accurate answers. Sharing a random example far from your real use case will not help you. I see nothing from your comment in your questionLucylud
@TemaniAfif Okay I updated the code to be closer example of the problem.Angelikaangelina
using grid areas, i solved this by conditionally applying grid-row: span 2 onto the row before the empty oneUnwonted
@Unwonted could create an answer showing your technique please?Angelikaangelina
@Géry Ogam the last set of edits I think make the code harder to read by obscuring the pattern. I understands it's more pure, and what I would also do for production code, but for the Q & A format like this. Thanks for the other beneficial changes though!Angelikaangelina
L
8

Don't define areas, define positions:

.parent {
   background: gray;
   padding: 16px;
   margin: 16px;
   display: grid;
   grid-gap: 16px;
}
[class^="child"] {
   background-color: red;   
}
.childa { grid-area: 1/1 } /* row / column */
.childb { grid-area: 1/2 }
.childc { grid-area: 2/1 }
.childd { grid-area: 2/2 }
.childe { grid-area: 3/1 }
.childf { grid-area: 3/2 }
.childg { grid-area: 4/1 }
<div class="parent">
<span class="childa">cell A</span>
<span class="childc">cell C</span>
<span class="childb">cell B</span>
<span class="childe">cell E</span>
<span class="childf">cell F</span>
<span class="childd">cell D</span>
</div>

<div class="parent">
<span class="childa">cell A</span>
<span class="childb">cell B</span>
<span class="childd">cell D</span>
</div>

Also like below:

.parent {
   background: gray;
   padding: 16px;
   margin: 16px;
   display: grid;
   grid-auto-flow:dense; /* don't forget this */
   grid-gap: 16px;
}
[class^="child"] {
   background-color: red;   
}
.childa,
.childc,
.childe { grid-column: 1 } 

.childb,
.childd,
.childf { grid-column: 2 }
<div class="parent">
<span class="childa">cell A</span>
<span class="childc">cell C</span>
<span class="childb">cell B</span>
<span class="childe">cell E</span>
<span class="childf">cell F</span>
<span class="childd">cell D</span>
</div>

<div class="parent">
<span class="childa">cell A</span>
<span class="childb">cell B</span>
<span class="childd">cell D</span>
</div>

<div class="parent">
<span class="childa">cell A</span>
<span class="childb">cell B</span>
<span class="childf">cell F</span>
</div>
Lucylud answered 19/1, 2022 at 19:47 Comment(4)
Impressive answer, applying it, but have not come right yet, but your code pen works well!Angelikaangelina
I am surprised this works so well because I thought areas was basically an alias for rows/columns, but there seems to be other subtle changes. Thank you this is really good! Well done! I was doubtful there was a solution when I posted it.Angelikaangelina
Just a sidenote on grid-gap: grid-gap is afaik deprecated/obsolete and an alias for gap. same for grid-row-gap which is row-gap and grid-column-gap which is column-gap. See hereCarven
It's not always possible to avoid using areas. Any ideas how to make it work with areas?Blueness

© 2022 - 2024 — McMap. All rights reserved.