When setting a parent element to display: flex
, its child elements align left-to-right like this:
Now, one of the neat things we can do with flexbox is change the direction so that child elements are stacked vertically on top of each other in a column. We can do that with the flex-direction
property (or with the flex-flow
shorthand):
Okay, cool. But how would I do something like this with CSS Grid? As in, let’s say I want all those child elements to be aligned like this:
1 3 5 7
--------
2 4 6 8
…instead of this:
1 2 3 4
--------
5 6 7 8
By default, when I set a parent element to use CSS Grid, the elements will be positioned left-to-right just like flexbox. In the example below I’m telling the grid to have 6 columns and 2 rows, then let the child elements fill up each column of the first row before they fill up the columns of the second. You know, standard line wrapping behavior.
.parent {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: repeat(2, 150px);
gap: 20px;
}
Basically what I want here is the opposite: I want our child elements to fill up column 1, row 1 and row 2, then move on to the next column. In other words, column wrapping! I know that if I create a grid with rows and columns I could individually place those elements into those positions. Like so:
.parent {
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: repeat(6, 150px);
}
.child-1 {
grid-column: 1;
grid-row: 1;
}
.child-2 {
grid-column: 1;
grid-row: 2;
}
.child-3 {
grid-column: 2;
grid-row: 1;
}
/* etc, etc. */
Okay, neat! This gets me what I want but it’s a giant pain having to individually set the position of each item. It feels like I’m using position: absolute
and it doesn’t feel particularly smart. So what if I just wanted this layout to be done for me, so that each new child element would align into the correct spot…correctly?
What I’m asking for (I think) is this: is there a CSS Grid version of flex-direction: column
?
Well, after searching around a bit, Rachel Andrew pointed me to the correct answer in her rather excellent playground, Grid by Example. And as you can see in this demo, Rachel shows us how to do just that:
Neato! Rachel does this with the grid-auto-flow
property: it tells a grid container how to fill the unoccupied space with child elements. So I can do that just by writing this:
.parent {
display: grid;
grid-auto-flow: column;
/* set up columns and rows here */
}
By default, child elements of a grid will fill up each column until a row is filled, then it’ll flow into the next beneath it. This is why the default for grid-auto-flow
is set to row
because we’re filling up rows of the grid first. But if we set it to column
, then each new element will fill up all the space of column 1 before moving on to column 2, etc.
.parent {
display: grid;
grid-auto-flow: column;
grid-template-columns: repeat(6, 1fr);
grid-template-rows: repeat(2, 150px);
}
This is what the flow part of grid-auto-flow
means and for the longest time I ignored the property because it seemed (don’t laugh) scary. Just reading the word grid-auto-flow
is enough to make me want to shut off my laptop and walk into the ocean.
But! It’s a pretty useful property and makes a ton of sense, especially if you think of it as the CSS Grid version of flex-direction
.
your article was really awesome and super helpful, thank you
this feels very close to allowing I’ve layout model, grid, to do tabular (generally, very horizontal in nature) on normal larger than phone, landscape screens, then switch direction so that each cell in a row appears stacked vertically for skinny portrait phones.
Hmmmm.
BTW, big points for honesty about being scared of the new concepts in IT. The burden on IT workers forced to constantly rewrite the wheel is horrible. Thanks for being honest.
Super cool, thank you !!
I’m still missing something… Is there a way to use it without knowing the number of rows ?
This line implies that you will have 2 rows
grid-template-rows: repeat(2, 150px);
And this one 6 columns
grid-template-columns: repeat(6, 1fr);
What if you had 30 items…
Any way to just say : split even between 2 columns and adjust the number of rows ?
Thanks
Probably not with Grid, but you can use Multicol. Set
columns: 4
instead ofdisplay: grid
, and you should get four balanced columns.Is there a way to wrap whole columns in rows’ direction when resizing viewport?
What I mean is to go from:
1 4
2 5
3 6
to
1
2
3
4
5
6
when the viewport is to narrow to accommodate two columns.
I understand that it would be somehow contradictory – changing auto-flow from row to column and to row again but maybe there is a way around?