0

I have a css grid set up using grid-template-areas. I have four rows; a row with two buttons, followed by a row with a div that conditionally renders (using jsx) based on whether the first button was clicked. The two last rows are identical in their setup.

HTML

<div className='wrapper'>
  <button className='button1'/>
  <button className='button2'/>
  {isDiv1Showing && (
  <div className='div1'>Content</div>
  )}
  <button className='button3'/>
  <button className='button4'/>
  {isDiv2Showing && (
  <div className='div2'>Content</div>
  )}
</div>

CSS

.wrapper {
  display: grid;
  grid-template-columns: 5fr 1fr;
  grid-template-rows: auto;
  grid-template-areas:
  "a1 a2"
  "a3 a3"
  "b1 b2"
  "b3 b3"
  ;
}

.button1 {
  grid-area: 'a1';
}

.button2 {
  grid-area: 'a2';
}

.div1 {
  grid-area: 'a3';
}

.. and the same for the next two rows.


What I expect to happen:

Scenario1: No button was pressed:

Row1; button1 button2
Row2: 
Row3: button3 button4
Row4: 

Scenario 2: The button in row1 was pressed:

Row1; button1 button2
Row2: div1
Row3: button3 button4
Row4: 

This is not what happens though - instead this happens:

Scenario 1:

Row1; button1 button2
Row2: button3 button4
Row3: 
Row4: 

Scenario 2

Row1; button1 button2
Row2: <div/> button3
Row3: button4
Row4: 

I guess I don't fully understand the behaviour of grid template areas, specifically when areas are left empty. Also it surprises me that button3 and button4 leaves their assigned grid areas to take up the space in a3, and I would like to know how I may prevent this?

I know that I can achieve the desired results by other means, e.g. flexbox or a different grid setup. My example here is obviously a simplified example and my specific problem includes many more rows which is why I'm going for a grid.

vsync
  • 118,978
  • 58
  • 307
  • 400
Jens
  • 11
  • 5

1 Answers1

3

The reason why the grid-area properties are not being respected is because you are wrapping them in quotes. If you inspect the element you will realize the browser reports an invalid value.

.button1 {
  grid-area: 'a1';
}

Invalid property value[1]

They should look like this instead:

.button1 {
  grid-area: a1;
}

Moreover, the reason why your grid row collapses in height is because you are missing the grid-auto-rows property: when all elements in the row has no content (e.g. your .div1 that is not rendered in the second row), it collapses to a height of 0. You will need to use it to assign a minimum height, e.g. grid-auto-rows: 20px and the likes of it.

.wrapper {
  display: grid;
  grid-template-columns: 5fr 1fr;
  grid-auto-rows: 20px;
  grid-template-areas:
  "a1 a2"
  "a3 a3"
  "b1 b2"
  "b3 b3"
  ;
}

.button1 {
  grid-area: a1;
}

.button2 {
  grid-area: a2;
}

.div1 {
  grid-area: a3;
}

.button3 {
  grid-area: b1;
}

.button4 {
  grid-area: b2;
}

.div2 {
  grid-area: b3;
}
<div class='wrapper'>
  <button class='button1'>Btn1</button>
  <button class='button2'>Btn2</button>

  <!-- Let's choose not to render it -->
  <!--
  <div class='div1'>Content</div>
  -->

  <button class='button3'>Btn3</button>
  <button class='button4'>Btn4</button>

  <div class='div2'>Content</div>

</div>
Terry
  • 63,248
  • 15
  • 96
  • 118
  • Gosh - my only explanation for wrongly using quotes in the grid area value is that it's friday.. Thx for a very elaborate answer! – Jens Feb 21 '20 at 09:56