If there is a conflict, do grid-column
and grid-row
always take precedence over order
in a grid?
Display Order: the order property
Flex and grid containers lay out their contents in order-modified document order, starting from the lowest numbered ordinal group and going up. Items with the same ordinal group are laid out in the order they appear in the source document.
The auto-placement algorithm works with the grid items in order-modified document order, not their original document order.
From the specification, it seems that order
is applied first, and then the placement algorithm runs to apply any necessary changes.
In the following snippet, a grid with four columns and one row orders its grid items in reverse-source order using the order
property.
#grid-container
{
display: grid;
grid-template-columns: 100px 100px 100px 100px;
grid-template-rows: 100px;
}
.grid-item
{
color: white;
background-color: darkblue;
border: 1px solid white;
}
.grid-item:nth-child(1)
{
order: 4;
}
.grid-item:nth-child(2)
{
order: 3;
}
.grid-item:nth-child(3)
{
order: 2;
}
.grid-item:nth-child(4)
{
order: 1;
}
body
{
background-color: black;
}
<div id = 'grid-container'>
<div class = 'grid-item'>1</div>
<div class = 'grid-item'>2</div>
<div class = 'grid-item'>3</div>
<div class = 'grid-item'>4</div>
</div>
In this snippet, the conflicting grid-column
and grid-row
properties are added, which take precedence over order
.
#grid-container
{
display: grid;
grid-template-columns: 100px 100px 100px 100px;
grid-template-rows: 100px;
}
.grid-item
{
color: white;
background-color: darkblue;
border: 1px solid white;
grid-row: 1 / 2;
}
.grid-item:nth-child(1)
{
order: 4;
grid-column: 1 / 2;
}
.grid-item:nth-child(2)
{
order: 3;
grid-column: 2 / 3;
}
.grid-item:nth-child(3)
{
order: 2;
grid-column: 3 / 4;
}
.grid-item:nth-child(4)
{
order: 1;
grid-column: 4 / 5;
}
body
{
background-color: black;
}
<div id = 'grid-container'>
<div class = 'grid-item'>1</div>
<div class = 'grid-item'>2</div>
<div class = 'grid-item'>3</div>
<div class = 'grid-item'>4</div>
</div>
Based on small tests like the ones above, and the specification, I think the answer is probably that the placement properties always take precedence over order
if there's a conflict. But it would be better to have a definite answer, or to know the cases where order
may take precedence.
I think the answer is probably that the placement properties always take precedence over order
We should not really talk about precedence since both don't do the same thing. The whole placement algorithm consider both order
and grid-*
properties to place the items. It doesn't consider only one of them.
From the Specification you can read:
The auto-placement algorithm works with the grid items in order-modified document order, not their original document order.
So the algorithm will consider the order of the items to place them. order: 1
will get placed first, order: 2
second, and so one BUT where they will get placed is a different story. I think your confusion is here.
The order
property don't place items, it defines when the items is getting placed. The placement is defined by the grid-*
property and following the below algorithm
Position anything that’s not auto-positioned.
Process the items locked to a given row.
Position the remaining grid items.
If the item has a definite column position:
If the item has an automatic grid position in both axes:
In your case, all the items fall into the step (2) since they have a defined column and row position so the browser will first place item4 because it has the order: 1
, then item3 and so on. But since all of them have a different place, you will notice nothing and you may thing order
is doing nothing.
Take another example where the items have the same place and you can see the effect of the order
property
#grid-container
{
display: grid;
grid-template-columns: 100px 100px 100px 100px;
grid-template-rows: 100px;
}
.grid-item
{
color: white;
background-color: darkblue;
border: 1px solid white;
grid-row: 1 ;
}
.grid-item:nth-child(1)
{
order: 4;
grid-column: 1;
}
.grid-item:nth-child(2)
{
order: 3;
grid-column: 2;
}
.grid-item:nth-child(3)
{
order: 2;
grid-column: 2;
}
.grid-item:nth-child(4)
{
order: 1;
grid-column: 4 ;
}
body
{
background-color: black;
}
<div id = 'grid-container'>
<div class = 'grid-item'>1</div>
<div class = 'grid-item'>2</div>
<div class = 'grid-item'>3</div>
<div class = 'grid-item'>4</div>
</div>
I am placing item2 and item3 at the same position but item2 is above because we first place item3 then item2 following the order
property
So there is no conflict between the properties and the browser will not run the order
first. The browser will place each item one by one following the order property and for each item we look at the grid-*
properties to know where to place it.
#grid-container {
display: grid;
grid-template-columns: 100px 100px 100px 100px;
grid-template-rows: 100px 50px;
}
.grid-item {
color: white;
background-color: darkblue;
border: 1px solid white;
width: 150%;
}
.grid-item:nth-child(1) {
order: 2;
grid-row: 1;
grid-column: 1;
}
.grid-item:nth-child(2) {
order: 1;
grid-column: 2;
}
body {
background-color: black;
}
<div id='grid-container'>
<div class='grid-item'>1</div>
<div class='grid-item'>2</div>
</div>
In the above, we first place item2 and then item1. I am explicitly creating an overlap using a big width to show than item1 is above because it's placed after even if both items aren't at the same place. Remove order
and the item2 will overlap item1
Take your example and create an overlap to see how items are stacked:
#grid-container {
display: grid;
grid-template-columns: 100px 100px 100px 100px;
grid-template-rows: 100px;
}
.grid-item {
color: white;
background-color: darkblue;
border: 1px solid white;
grid-row: 1 / 2;
width: 120%;
}
.grid-item:nth-child(1) {
order: 4;
grid-column: 1 / 2;
margin-top: 50px;
}
.grid-item:nth-child(2) {
order: 3;
grid-column: 2 / 3;
margin-top: 30px;
}
.grid-item:nth-child(3) {
order: 2;
grid-column: 3 / 4;
margin-top: 10px;
}
.grid-item:nth-child(4) {
order: 1;
grid-column: 4 / 5;
}
body {
background-color: black;
}
<div id='grid-container'>
<div class='grid-item'>1</div>
<div class='grid-item'>2</div>
<div class='grid-item'>3</div>
<div class='grid-item'>4</div>
</div>