I am trying to span my second grid item over two rows.
I am able to achieve what I am looking for using the grid-row: span 2
syntax. However I would like to achieve the same result using the grid-row: x/y
syntax, where x and y are numeric values.
Problem is, the second syntax is producing unexpected results.
May someone please help me understand what it is I am doing wrong?
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
body {
font-family: Impact, Haettenschweiler, 'Arial Narrow Bold', sans-serif;
font-size: 16px;
line-height: 1.5;
color: rosybrown;
background: #ffff;
}
.container {
display: grid;
max-width: 960px;
padding: 10px;
margin: 0;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: auto;
}
.item {
background: steelblue;
color: white;
font-size: 20px;
padding: 20px;
border: skyblue 1px solid;
}
.item:nth-child(1) {
grid-column: 1/3;
background-color: springgreen;
}
.item:nth-child(2) {
background-color: royalblue;
grid-row: 1/3;
}
.item:nth-child(3) {
background: darkred;
}
.item:nth-child(5) {
grid-column: 1/4;
}
<div class="container">
<div class="item"> item1 </div>
<div class="item"> item2 </div>
<div class="item"> item3 </div>
<div class="item"> item4 </div>
<div class="item"> item5 </div>
</div>
I tried reading through the CSS to find the cause of the problem, and I also tried using different values.
2
Answers
Solution
Add
grid-row: 1
to the first item, orgrid-column: 3
to the second item.OR
Explanation
Line-Based Placement
Let’s start by keeping in mind that
grid-row
andgrid-column
are shorthand properties for:grid-row-start
/grid-row-end
grid-column-start
/grid-column-end
Item #1 is set to span across the first two columns.
But it has no rows defined. Therefore,
grid-row
defaults toauto
.Item #2 is set to span the first two rows.
But it has no columns defined. Therefore,
grid-column
defaults toauto
.Side note: Because the explicit grid has only one row defined (
grid-template-rows: auto
), and no height defined, Item #2 is actually spanning across two rows—one explicit, one implicit—not just one as it appears. (This matter is worthy of another question.)The Grid Item Placement Algorithm
The grid item layout process is handled by the Grid Item Placement Algorithm. One of the first steps in the process is this:
Therefore:
auto
).auto
).This is how Item #2 gets placed above Item #1. Defined rows and columns have precedence over undefined rows and columns—the latter subject to more control by the algorithm.
As mentioned at the top, the simplest solution is to remove the
auto
variable from the process. You can do this by addinggrid-row: 1
to the first item, orgrid-column: 3
to the second item.span
grid-row: 1 / 3
is shorthand for:grid-row-start: 1
grid-row-end: 3
grid-row: span 2
is equivalent togrid-row: span 2 / auto
, which is shorthand for:grid-row-start: span 2
grid-row-end: auto
When you switch from
grid-row: 1 / 3
togrid-row: span 2
, you remove thegrid-row-start: 1
component. In other words, you unlock the item from the first row. The algorithm now has more control, moving the item to its natural position.You could take advantage of
grid-template-areas
&grid-area
, like so: