1

Is there a way to make a grid item span over all free space automatically?

For example here, the grid has two rows and two columns. In the first row, the second column is free, so I'd like to span the item (as it does when I explicitly set grid-column-end: 3).

But I do not want to calculate the spans, but let the browser do that.

Edit: to make the question clearer: the container is only allowed to specify the number of rows and cols. The items are only allowed to specify the row- and col-start but no spans and -ends so if there is an item with row-start: i followed by an item with row-start: i+1+n and no items with row-start: i+1+m with m<n the item with row-start: i should automatically span n.

<div style="display: grid; gap: 5px;">
  <div style="
        background: red;
        grid-row-start: 1;
        grid-column-start: 1;
        /* how can I get rid of this */
        grid-column-end: 3;">1 1</div>
  <div style="
        background: red;
        grid-row-start: 2;
        grid-column-start: 1;">2 1</div>
  <div style="
        background: red;
        grid-row-start: 2;
        grid-column-start: 2;">2 2</div>
</div>
Dill
  • 1,943
  • 4
  • 20
  • 28
  • 2
    with CSS grid you cannot. You need to explicitly define the "span" or the position. but you can try grid-column-end: -1 which means "to the last column" – Temani Afif Jan 23 '23 at 12:25
  • read this article: https://stackoverflow.com/questions/45799207/how-to-make-css-grid-items-take-up-remaining-space – Gabesz Juhász Jan 23 '23 at 12:43
  • @TemaniAfif this will always span the whole row, I only want to span unused cells. – Dill Jan 23 '23 at 12:44
  • @GabeszJuhász adding ``` grid-template-columns: 1fr min-content; grid-template-rows: 1fr 1fr; ``` will just make the second column smaller, but not span item `1 1` – Dill Jan 23 '23 at 12:54

3 Answers3

1

First off,

You cannot automatically span grid items over all free space.

Without explicitly setting the grid-column-end property or calculating the spans yourself - it would be best to resort to something like flexbox.

The way the grid layout works is that it uses the grid-row-start, grid-column-start, grid-row-end and grid-column-end properties to determine the size and position of each item within the grid. Without explicitly setting these properties, the browser will not know how to position the items and you'll inevitably end up with a gigantic mess. Grids aren't like flexbox since they aren't really smart and require you to explicitly set nearly every aspect of it in order to be rendered properly. They aren't really responsive either.

If you do decide to continue sticking with CSS Grid, one option would be to use JavaScript to calculate the spans based on the position of the other items on the grid and then set these properties dynamically. This is more complex and will add more overhead to your code - making it less easy to maintain

Another option (which I personally recommend) is to use flexbox instead of CSS Grid. A flexbox automatically adjusts the size of its flex items based on the available space, and you can use the flex-wrap property to wrap the items onto new rows if there is not enough space.

Flexbox is also responsive. CSS Grid is not. Therefore, the pros weigh out the cons when compared to CSS Grid.

Joe
  • 415
  • 1
  • 5
  • 15
-1

I don't know if that can totally suits you but one way would be to defined class with span 2 and span1.

.row {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: 1fr auto;
}

.col1 {
  grid-column: auto / span 2;
}

.col2 {
  grid-column: auto / span 1;
}
<div class="row">
  <div class="col1" style="background-color: red">
    1 1
  </div>
</div>
<div class="row">
  <div class="col2" style="background-color: green">
    2 1
  </div>
  <div class="col2" style="background-color: blue">
    2 2
  </div>
</div>
pier farrugia
  • 1,520
  • 2
  • 2
  • 9
-1

we can put css grid-column: 1 / -1; as it will automatically fill the cell to the last. So basically we don't need to provide grid-column-end with specific number.

.row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
}

.col-stretch{
  grid-column: 1 / -1;
}
<div class="row">
  <div class="col-stretch" style="background-color: red">
    1 1
  </div>
</div>
<div class="row">
  <div class="col" style="background-color: green">
    2 1
  </div>
  <div class="col" style="background-color: gray">
    2 2
  </div>
  <div class="col" style="background-color: yellow">
    2 3
  </div>
</div>
Dakshank
  • 689
  • 4
  • 15