In CSS Grid Layout, Do We Count the Span Even Starting on Implicit Grid Lines

How to span to the last column in an implicit grid?

Why shouldn't it work on implicit grids?

Because we can easily run on undefined cases1 or a cyclic dependency. If it was the implicit grid, it means that we need to first place all the others element to identify the implicit grid then we place our element BUT if we place our element we will obtain another implicit grid so technically you cannot know the implicit grid without placing the element.

The idea behind the implicit grid is to place the element that doesn't have anything defined for their placement automatically after placing the ones with known places.


You can overcome this by using some hacks either for row or column:

Stretch an element to the end of the automatically calculated grid, not just the explicit grid

Forcing a column to be empty in a responsive grid layout


1 A basic example:

.grid {  display: grid;  grid-template-columns: 50px;  grid-gap: 5px;  grid-auto-flow: column;  grid-auto-columns:50px;}
.grid>span { height: 50px; background: red;}
.grid>span.place { grid-column: 1 / -1; background: blue;}
<div class="grid">  <span></span>  <span class="place"></span></div>

Can a grid cell span every column without specifying the number of columns?

Unfortunately, no. This is not possible with the current version of CSS Grid (Level 1).

For a grid area to expand across all columns or rows, using the negative integer method (1 / -1), you'll need an explicit grid container.

From the 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 (starting from 1 for the start-most explicit line), while negative indexes count from the end side (starting from -1 for the end-most explicit line).

and 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.

Make a grid item span to the last row / column in implicit grid

You can add grid-row-start to that boxes css, and set it to span an absurdly high number.

.container {  display: grid;  grid-template-columns: repeat(3, minmax(10rem, 1fr)) [last-col] 35%;   grid-template-rows: auto [last-line];}
.box { background-color: blue; padding: 20px; border: 1px solid red;}
.box:nth-child(3) { background-color: yellow; grid-column: last-col / span 1; grid-row: 1 / last-line; grid-row-start: span 9000;}
<div class="container">  <div class="box"></div>  <div class="box"></div>  <div class="box">3</div>  <div class="box"></div>  <div class="box"></div>  <div class="box"></div>  <div class="box"></div>  <div class="box"></div>  <div class="box"></div>  <div class="box"></div>  <div class="box"></div></div>

Using negative integers with implicit rows in CSS Grid

You can only use negative integers in an explicit grid.

See the Grid spec here:

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
(starting from 1 for the start-most explicit line), while negative
indexes count from the end side (starting from -1 for the end-most
explicit line).

and 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.

Making a grid area span an entire column / row, including implicit tracks, when the number of tracks in the grid is unknown, is not possible in CSS Grid Level 1, unless you want to try to hack it.

How to reason an implicit css grid area without all 4 edges named?

From my understanding, you have defined all the grid lines to have the same name col-start but you never defined any grid lines called col-end and the trick is here.

When using grid-area: col we need to either have an area called col or grid lines called col-start and col-end. We don't have any named area and we only have col-start so the browser will implicitly create a grid line called col-end to place your element and this will result in 13 columns in total and not 12

Here is an example where I am reducing the number of column to better see

.wrapper {
display: grid;
grid-template-columns: repeat(5, [col-start] 1fr);
grid-auto-columns: 100px;
gap: 10px;
border: 1px solid;
}

.content {
grid-area: col;
}
<div class="wrapper">
<div class="content">content</div>
</div>

Row span without affecting other rows

Your rows are set to auto height.

#wrapper {
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
grid-template-rows: repeat(12, minmax(0, 1fr)); <-- ignored; overruled
grid-template-rows: auto; <-- winning rule
}

This means that the height of the first row (explicit grid) will be determined by content height.

The height of the remaining rows (implicit grid) will also be determined by the content height, because the default setting for grid-auto-rows is also auto.

It also means that a CSS Grid rule goes into effect: Free space among grid tracks with auto sizing is divided equally among them.

§ 11.8. Stretch auto
Tracks

This step expands tracks that have an auto max track sizing function
by dividing any remaining positive, definite free space equally
amongst them. If the free space is indefinite, but the grid container
has a definite min-width/height, use that size to calculate the free
space for this step instead.

So when #left1 and #left2 share the same tracks with #right1, the free space (created in the left areas because the right area is taller) is distributed equally among the left areas.

But if the #right1 area is made to span into an empty, undefined row (let's say, from grid-row: 3/5 to grid-row: 3/6) it's no longer bound to the #left1 and #left2 tracks, and the auto stretch algorithm no longer applies.

#wrapper {
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
grid-template-rows: repeat(12, minmax(0, 1fr));
grid-template-rows: auto;
}

#navigation {
grid-column-start: 1;
grid-column-end: 13;
background-color: #CCC;
grid-row: 1;
}

#hero {
grid-column-start: 1;
grid-column-end: 13;
background-color: #BBB;
grid-row: 2;
}

#left1 {
grid-column-start: 1;
grid-column-end: 4;
grid-row: 3;
background-color: #AAA;
}

#left2 {
grid-column-start: 1;
grid-column-end: 4;
grid-row: 4;
background-color: #DDD;
}

#right {
grid-column-start: 4;
grid-column-end: 13;
/* grid-row: 3/5; */
grid-row: 3/6; /* new */
background-color: #EEE;
}
<div id="wrapper">
<div id="navigation">NAVIGATION</div>
<div id="hero">HERO IMAGE</div>
<div id="left1">Left1</div>
<div id="left2">Left2</div>
<div id="right">Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right
Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right </div>
</div>

How does grid-row: 1 / -1 actually work? (references needed)

grid-row:1/-1 means grid-row-start:1 and grid-row-end:-1 and if you check the specification you can read:

Numeric indexes in the grid-placement properties count from the edges of the explicit grid. Positive indexes count from the start side (starting from 1 for the start-most explicit line), while negative indexes count from the end side (starting from -1 for the end-most explicit line).

The trick is the explicit grid. In your case you didn't define any explicit rows and your elements will be placed automatically generating new rows we call the implicit grid

The grid-template-rows, grid-template-columns, and grid-template-areas properties define a fixed number of tracks that form the explicit grid. When grid items are positioned outside of these bounds, the grid container generates implicit grid tracks by adding implicit grid lines to the grid. These lines together with the explicit grid form the implicit grid.

and

...If these properties don’t define any explicit tracks the explicit grid still contains one grid line in each axis.

So grid-row:1/-1 will not consider the grid structure after placing all the elements but will consider the intial definition of the grid before placing any element and this grid contain 2 columns (defined by grid-template-columns: max-content 1fr) and 0 rows.

Related: How to span to the last column in an implicit grid?



Related Topics



Leave a reply



Submit