Search code examples
cssgridcss-grid

Make a grid column span the entire row


Imagine we have two CSS grid containers with a dynamic columns count based on width:

display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));

The grid works perfectly, but what if we need to have another grid to have the first column to be same as in another grid with the code shown above, but it's another column to span through more cells - depending on how many cells are in the current row?

To better understand the issue, there are images:

TargetDesign

On a narrower wrapper:

TargetDesign2

We would need to apply something like grid-column: span ALL (if something like that exists), with meaning that ALL = till the end of the current row.

It is really important that "First" column should always align with the "1" column.

The code to run the example is here:

.grid div {
  /* Not important fancy styles */
  height: 40px;
  text-align: center;
  padding-top: 20px;
}

.grid {
  width: 350px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  background-color: silver;
}

.grid-second {
  background-color: red;
}

.grid-another {
  background-color: purple;
  border: 1px solid gray;
}
<div class="grid">
  <div class="grid-first">
    First
  </div>
  <div class="grid-second">
    Second (Want till end)
  </div>
</div>
<!-- Another same grid -->
<div class="grid">
  <div class="grid-another">
    1
  </div>
  <div class="grid-another">
    2
  </div>
  <div class="grid-another">
    3
  </div>
  <div class="grid-another">
    4
  </div>
</div>

PS: Please do not post solutions using a media query. I am interested in any (even a little hacky) solution, which will work without usage of media queries.


Solution

  • Here are two interesting sections in the CSS Grid specification:

    7.1. The Explicit Grid

    Numeric indexes in the grid-placement properties count from the edges of the explicit grid. Positive indexes count from the start side, while negative indexes count from the end side.

    also here...

    8.3. Line-based Placement: the grid-row-start, grid-column-start, grid-row-end, and grid-column-end properties

    If a negative integer is given, it instead counts in reverse, starting from the end edge of the explicit grid.

    In other words, when dealing with an explicit grid, which means a grid defined by these properties:

    • grid-template-rows
    • grid-template-columns
    • grid-template-areas
    • grid (which is the shorthand for the three properties above, among others)

    ... you can make a grid area span all columns by setting this rule:

    grid-column: 1 / -1;
    

    That tells the grid area to span from the first column line to the last column line, which I believe meets your stated objective:

    "We would need to apply something like grid-column: span ALL (if something like that exists), with meaning that ALL = till the end of current row."

    jsFiddle demo

    .grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
      background-color: silver;
    }
    
    .grid-second {
      grid-column: 2 / -1;
      background-color: red;
    }
    
    
    /* Not important fancy styles */
    
    .grid div {
      height: 40px;
      text-align: center;
      padding-top: 20px;
    }
    
    .grid-another {
      background-color: purple;
      border: 1px solid gray;
    }
    <div class="grid">
      <div class="grid-first">First</div>
      <div class="grid-second">Second (Want till end)</div>
    </div>
    <!-- Another same grid -->
    <div class="grid">
      <div class="grid-another">1</div>
      <div class="grid-another">2</div>
      <div class="grid-another">3</div>
      <div class="grid-another">4</div>
      <div class="grid-another">1</div>
      <div class="grid-another">2</div>
      <div class="grid-another">3</div>
      <div class="grid-another">4</div>
      <div class="grid-another">1</div>
      <div class="grid-another">2</div>
      <div class="grid-another">3</div>
      <div class="grid-another">4</div>
    </div>