I’m trying to understand what’s happening with the grid-column
property in what’s supposed to be a single row.
I have a simple grid of four items with grid-template-columns
, where I want to reverse the last two. I have defined the grid with a single row with grid-template-rows
. I position them using individual grid-column
properties.
div#buttons {
display: grid;
grid-template-columns: auto auto auto auto;
grid-template-rows: auto;
button#one {
grid-column: 1/2;
}
button#two {
grid-column: 2/3;
}
button#three {
grid-column: 4/5;
}
button#four {
grid-column: 3/4;
/* grid-area: 1/3/2/4; */
}
}
<div id="buttons">
<button id="one">One</button>
<button id="two">Two</button>
<button id="three">Three</button>
<button id="four">Four</button>
</div>
When I run this, I find that the last two items are reversed, but the last item, now in the 3rd position, has dropped to the next line.
I thought that using grid-column
would simply apply their column position, and I can’t see where the extra line comes from.
If I use the commented-out grid-area
property which forces the list item in the first and only row, then it works as planned.
There’s nothing I can find in the documentation which explains this.
The default grid-auto-flow
value uses an auto-placement algorithm that tries to maintain the normal reading order of the elements, i.e. reading left-to-right and then top to bottom in western documents. So since button #four
is after button #three
in the DOM document, to maintain that order it must be placed on a new row.
You can change this auto-placement choice by adding grid-auto-flow: dense;
However, changing the reading order comes with risks. Think about users using assistive technology. Make sure that they too experience your content the way you intend. This is one reason why dense
is not the default.
div#buttons {
display: grid;
grid-template-columns: auto auto auto auto;
grid-template-rows: auto;
grid-auto-flow: dense;
button#one {
grid-column: 1/2;
}
button#two {
grid-column: 2/3;
}
button#three {
grid-column: 4/5;
}
button#four {
grid-column: 3/4;
/* grid-area: 1/3/2/4; */
}
}
<div id="buttons">
<button id="one">One</button>
<button id="two">Two</button>
<button id="three">Three</button>
<button id="four">Four</button>
</div>