This post describes how to create a horizontal grid with 2 rows and infinite columns using CSS grid. This technique uses display: grid
, which finally has decent browser coverage.
Like CSS flex(box), CSS grid is incredibly flexible for creating relatively complex layouts and making seemingly simple ones, well simple (which wasn’t always the case, like centring content both vertically and horizontally).
Making a grid that scrolls horizontally using CSS grid & grid-auto-flow
Scrolling up and down is the default way to consume web page content. In order to scroll vertically to consume the content, we can need to tell the browser it’s okay to overflow on the x-axis and we need to tell the content it doesn’t need to wrap to the viewport.
There are a few ways to do this, but this post will demonstrate the grid
way:
.grid.scroll-x {
display: grid;
grid-auto-flow: column;
/* should, in theory, work without overflow-x */ overflow-x: scroll;
}
As can be seen in the code above, the grid-auto-flow
property is the key here. Used in conjunction with display: flex
and set to column
will tell the browser to render the element’s children as columns, which is what we want!
In order to reach the solution, this post set out to achieve all that’s needed now is to spread this grid element’s children over 2 rows. Fortunately, using grid
this is really easy.
Making a horizontal grid with 2 rows
The code above will render the horizontal elements, as required. If we introduce another property to this code snippet, grid-template-rows
, as per the following code, the element’s children will now be not only horizontally scrollable but they will also be rendered over 2 rows:
.grid.scroll-x--rows-2 {
display: grid;
/* auto auto is telling the browser to render two rows, if needed */ grid-template-rows: auto auto;
grid-auto-flow: column;
overflow-x: scroll;
}
This is perfect, just what was needed, and it was achieved with just 3 lines of CSS grid
properties (plus overflow-x: scroll
you feel the need to include it). However, there’s one small caveat; the layout’s rendered in a reversed ‘N’ order, with each column output, then the rows for that column. This outputs the first 2 elements in rows, then adds subsequent elements as columns to the right (as modelled below). This means that if the layout was designed for 2 columns there would need to be at least 3 items to render a second column, but this can be handled with the logic to make sure there are at least 3 items before applying the grid-template-rows
property.
Conclusion
The display: grid
CSS property is incredibly flexible and I think this scenario demonstrates a great use-case. Yes, this could have been done in other ways, for example, I used negative margins to create this horizontal masonry layout of cards, but the CSS grid
approach feels cleaner and more robust.
If you’d like to implement something like this in your project, please get in touch as we’re passionate about making the web look great.