Search code examples
htmlcssalignmentcss-grid

Dynamic rows using CSS Grid


I'm using Grid to present some data. I would like to have a layout where the first row is headers, the second row is sub-headers and the third is the main content. This is quite simple to achieve using the grid-template-areas property for the grid-container. My problem is that i'd like the first row to be generated only once whereas the second and third rows should be dynamic.

I am stuck trying to get the first two rows right so I will only refer to those two in my example.

I have my CSS grid container defined as follows:

.grid-container {
      display:grid;
      grid-template-columns: repeat(3, 1fr);
      grid-template-rows: auto;
      grid-template-areas:
         "header1 header2 header3"
         "subheader1 . subheader2";
}

.header-item-1 {
     grid-area: header1;
}

.header-item-2 {
     grid-area: header2;
}

.header-item-3 {
     grid-area: header3;
}

.sub-header-item-1 {
     grid-area: subheader1;
}

.sub-header-item-2 {
     grid-area: subheader2;
}

My html is as follows:

<ul class="grid-container">
    <li class="header-item-1">header1</li>
    <li class="header-item-2">header2</li>
    <li class="header-item-3">header3</li>

<!-- ko foreach: { data: subheaderItem, as: 'subheader' } -->

    <li class="sub-header-item-1" data-bind="text: subheader.name"></li>
    <li class="sub-header-item-2" data-bind="text: subheader.type></li>

<!-- /ko -->
</ul>

What this produces is a layout where the first row is correct, the second row has the correct layout but all iterations of the sub-headers are placed in the same cells like:

 *        *       *
***              ***

What i'm after is:

 *        *       *
 *                *
 *                *
 *                *
....

Would appreciate any tips on how to get this done ;)


Solution

  • You can remove grid-template-areas (same grid areas will overlap - see another example here) and use a 3-column layout using grid-template-columns: repeat(3, 1fr) and then setting grid-column: 1 for sub-header-item-1 and grid-column: 3 for sub-header-item-2.

    See demo below:

    .grid-container {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      grid-template-rows: auto;
    }
    
    .sub-header-item-1 {
      grid-column: 1;
    }
    
    .sub-header-item-2 {
      grid-column: 3;
    }
    <ul class="grid-container">
      <li class="header-item-1">header1</li>
      <li class="header-item-2">header2</li>
      <li class="header-item-3">header3</li>
      <li class="sub-header-item-1">1</li>
      <li class="sub-header-item-2">3</li>
      <li class="sub-header-item-1">1</li>
      <li class="sub-header-item-2">3</li>
      <li class="sub-header-item-1">1</li>
      <li class="sub-header-item-2">3</li>
    </ul>