3

TL;DR: Codepen https://codepen.io/veleek/pen/YmJGjY shows that grid cell with display: none seems to cause adjacent cell to take up less space instead of collapsing to nothing.

I'm creating a simple CSS Grid layout with a banner at the top with a logo, title, link bar, and a content block underneath.

Rough layout

For pages without nav links I'd like to collapse the nav section so that the title takes up the entire space. Effectively I want that grid cell to be 0px tall.

Unfortunately, when I set display: none on that cell, it disappears but it seems to take up MORE space. This actually causes the title to collapse itself down to be SMALLER then when that cell is present.

Title collapsing to be smaller

The image size is not fixed at 150px and I'd prefer to avoid fixed sizes if possible. I just want to force that grid row to have 0 height when it's empty. I've tried a bunch of combinations of display:block/flex, align-items/justify-content/etc.: stretch/center/etc. but nothing seems to work.

I've got a CodePen showing the issue here: https://codepen.io/veleek/pen/YmJGjY

Ben Randall
  • 1,205
  • 10
  • 27
  • I believe this issue is more thoroughly answered here: https://stackoverflow.com/questions/50708974/how-do-you-collapse-unused-row-in-a-css-grid – Peter Chapman Sep 16 '22 at 18:51

3 Answers3

9

The problem is related to the definition of auto for a grid row. According to grid-row-template MDN docs auto is:

Is a keyword that is identical to maximal content if it's a maximum. As a minimum it represents the largest minimum size (as specified by min-width/min-height) of the grid items occupying the grid track.

So when there is content in the track, it acts as a maximum and sizes correctly. But when there is no content in the clue-nav element, it appears to fallback to the minimum definition, and since the only grid item occupying the track is the image in clue-logo so the minimum ends up getting set to a much larger value. As everything resolves itself, the "empty" grid cell gets a bunch more space, and the clue-title grid cell ends up taking up the actual "minimum" amount of space that it needs.

To work around this issue, instead of setting the height to auto, you can use minmax(0, auto). This allows the actual minimum height of the row to go to zero instead of the clue-logo height, and it properly collapses when clue-nav is hidden.

I stumbled on this while fiddling around with Sølve's suggested answer, I noticed a bit more odd behavior around how it would decide to resize the row. So kudos to him for helping me stumble onto the right answer.

Ben Randall
  • 1,205
  • 10
  • 27
  • Cool! Creative way to solve it with with minmax! Way over my head This answer makes me want to dive deeper in to css grid – Sølve T. Aug 11 '19 at 13:36
1

You can set: grid-template-rows: auto 1fr;

Alex
  • 11
  • 1
0

You can use grid-row-start and set it to start at the first row:

#clue-title1, #clue-title2 {
    grid-area: clue-title;
    grid-row-start: 1;
}

div {
  border: 1px red solid;
} 

#clue-wrapper1, #clue-wrapper2 {
    display: grid;
    grid:
        "clue-logo clue-nav" auto
        "clue-logo clue-title" auto
        "clue-content clue-content" 1fr
        / auto 1fr;
}

#clue-logo1, #clue-logo2
{
    grid-area: clue-logo;
    
    display: flex;
    align-content: center;
}

#clue-nav1, #clue-nav2 {
    grid-area: clue-nav;
}

#clue-nav2 {
   display: none;
}

#clue-title1, #clue-title2 {
    grid-area: clue-title;
    grid-row-start: 1;
}

#clue-content1, #clue-content2 {
    grid-area: clue-content;
    min-height: 100px;
}
<div id="clue-wrapper1">
  <div id="clue-logo1"><img src="https://via.placeholder.com/150"/></div>
  <div id="clue-nav1">Sample navigation items</div>
  <div id="clue-title1"><h1>Title</h1></div>
  <div id="clue-content1">Content</div>
</div>

<hr/>

<div id="clue-wrapper2">
  <div id="clue-logo2"><img src="https://via.placeholder.com/150"/></div>
  <div id="clue-nav2">Sample navigation items</div>
  <div id="clue-title2"><h1>Title</h1></div>
  <div id="clue-content2">Content</div>
</div>
Sølve T.
  • 4,159
  • 1
  • 20
  • 31
  • This seems to work for relatively simple scenarios, but it's a little bit more difficult for dynamic things where content may be added or removed from the `#clue-nav` section at runtime. In order to handle that I would have to add and remove `grid-row-start: 1;` whenever that happens. Additionally, if I change the grid layout to add another row above, I'll need to go through and modify all that. I'd really like a solution that allows the grid cell to collapse down to zero height when empty. – Ben Randall Aug 11 '19 at 03:56