39

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jurosh
  • 6,984
  • 7
  • 40
  • 51
  • For anyone wondering, if you could the same thing with a column, while autoflowing into implicitly generated rows, then no, not possible. The lines will only have positive integer names, so the solution with -1 reference wouldn't work. – Ev0oD Jan 11 '21 at 19:23

1 Answers1

100

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>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • Thanks, that's really interesting solution - first time I was usage of it, great! Maybe you might know, is possible to make it wrap to next line when there is no space for 2 columns, but just for single. Cause with 2 / -1, it probably needs to start always from second column.. – Jurosh Nov 16 '17 at 20:39
  • For the second column in the first container to wrap to the second row, in order to remain consistent with the second container, it would have to know when the second container has become one column. – Michael Benjamin Nov 16 '17 at 20:45
  • There's no way to associate them. They are grid items in separate containers. You would need to put all items in the same container or use a media query. – Michael Benjamin Nov 16 '17 at 20:45
  • Thank you! Had also expected a special keyword like `span ALL` but `grid-column: 1 / -1` is valid syntax which does just that! That way I can set a grid item to always span the entire row regardless of whether the parent grid-container may changes its column count. – porg Aug 02 '23 at 11:53