Search code examples
htmlcsscss-grid

Insert full width block inside grid layout


I'm creating a page layout that Google Images has some time ago. There is a grid of images with large full with section under selected image. And I'm curious is it possible to mark up this page with css disaply: grid property.

grid page template

At first I made container with three columns. Everything is great:

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 20px;
}

.item {
  border: 1px solid;
  height: 20px;
}
<div class="container">
  <div class="item"></div>  
  <div class="item"></div>  
  <div class="item"></div>  
  <div class="item"></div>  
</div>

But I have no idea, how to insert description block inside this grid. I'm not sure is it possible at all. I'm going to toggle descriptions via display: none | block. The number of images and rows is unknown.

.container {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-gap: 20px;
}

.item {
  border: 1px solid;
  height: 20px;
}

.item__description {
  border: 1px solid red;
  height: 10px;
}
<div class="container">
  <div class="item">
    <div class="item__description">Description of the first item</div>
  </div>
  <div class="item"></div>
  <div class="item"></div>  
  <div class="item"></div>
  <div class="item__description">Description of the last item. No matter where to place this description: inside or outside 'item' block</div>
</div>

The idea is to create this layout without any js DOM manipulations.


Solution

  • Set the grid-auto-flow: row dense; on the .container. Move the .item__description outside of item, and set grid-column: 1 / span 3; on it.

    .container {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      grid-auto-flow: row dense;
      grid-gap: 20px;
    }
    
    .item {
      border: 1px solid;
      height: 20px;
    }
    
    .item__description {
      grid-column: 1 / -1;
      border: 1px solid red;
      height: 20px;
    }
    <div class="container">
      <div class="item"></div>
      <div class="item__description">Description of the first item</div>
      <div class="item"></div>
      <div class="item"></div>
      <div class="item"></div>
      <div class="item__description">Description of the last item. No matter where to place this description: inside or outside 'item' block</div>
    </div>

    This will also work with display toggling (hover an item):

    .container {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      grid-auto-flow: row dense;
      grid-gap: 20px;
    }
    
    .item {
      border: 1px solid;
      height: 20px;
    }
    
    .item__description {
      display: none;
      grid-column: 1 / -1;
      border: 1px solid red;
      height: 20px;
    }
    
    .item:hover + .item__description {
      display: block;
    }
    <div class="container">
      <div class="item">Hover Me 1</div>
      <div class="item__description">Description of the item 1</div>
      <div class="item">Hover Me 2</div>
      <div class="item__description">Description of the item 2</div>
      <div class="item">Hover Me 3</div>
      <div class="item__description">Description of the item 3</div>
      <div class="item">Hover Me 4</div>
      <div class="item__description">Description of the item 4</div>
    </div>