Search code examples
htmlcsscss-grid

How to get the effect of grid layout's grid-template-columns with a variable number of columns?


I have a div containing a variable number of children. This code is generated and I can't modify it. So with only CSS I need to display divs in a table with two rows:

  • The first row contains only the first div (100% width)
  • The other div share the second row : each div will have the same width an the should totally fill the row.

I tried with a grid layout + grid-template-columns but using grid-template-columns does not because because it supposes I know the number of columns. For example, the following snippet only works if there are 4 children

.parent {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
}

.child:nth-child(1) {
    grid-column: 1/-1;
}
Test with 3 children
<div class="parent" style="background-color:yellow;" >
  <div class="child" style="background-color:red;">1</div>
  <div class="child" style="background-color:blue;">2</div>
  <div class="child" style="background-color:green;">3</div>
</div>
Test with 4 children
<div class="parent" style="background-color:yellow;" >
  <div class="child" style="background-color:red;">1</div>
  <div class="child" style="background-color:blue;">2</div>
  <div class="child" style="background-color:green;">3</div>
  <div class="child" style="background-color:orange;">4</div>
</div>
Test with 5 children
<div class="parent" style="background-color:yellow;" >
  <div class="child" style="background-color:red;">1</div>
  <div class="child" style="background-color:blue;">2</div>
  <div class="child" style="background-color:green;">3</div>
  <div class="child" style="background-color:orange;">4</div>
  <div class="child" style="background-color:purple;">5</div>
</div>


Solution

  • Flexbox can do what I think you are after

    .parent {
      display: flex;
      flex-wrap: wrap;
      margin-top: 1em;
    }
    
    .child {
      flex: 1;
      padding: .25em 0;
      color:white;
      font-size:1.25em;
    }
    
    .child:nth-child(1) {
      flex: 1 0 100%;
    }
    Test with 3 children
    <div class="parent" style="background-color:yellow;">
      <div class="child" style="background-color:red;">1</div>
      <div class="child" style="background-color:blue;">2</div>
      <div class="child" style="background-color:green;">3</div>
    </div>
    Test with 4 children
    <div class="parent" style="background-color:yellow;">
      <div class="child" style="background-color:red;">1</div>
      <div class="child" style="background-color:blue;">2</div>
      <div class="child" style="background-color:green;">3</div>
      <div class="child" style="background-color:orange;">4</div>
    </div>
    Test with 5 children
    <div class="parent" style="background-color:yellow;">
      <div class="child" style="background-color:red;">1</div>
      <div class="child" style="background-color:blue;">2</div>
      <div class="child" style="background-color:green;">3</div>
      <div class="child" style="background-color:orange;">4</div>
      <div class="child" style="background-color:purple;">5</div>
    </div>