A Simple Primer for CSS Grid Layout
Grids on the web have a storied history. I remember a Webmonkey (RIP) article
that explained how to set up a simple grid using
framesets.
Times were simpler then. Developers started abusing tables. Then we just started
floating everything this way and that. We got tired of needing to
self-clear child elements so
we started inline-block
ing everything. We declared
flexbox to be the saviour
of everything but we’ve never really been able to stop
hacking our way through it.
CSS Grid Layout aims to solve a number of the problems that developers run into when creating lots of different types of web applications. We’re going to look at a simple case today to show off the easy side of CSS Grid Layout.
Our Grid
We’re going to be working with a simple grid of products. Having worked within the ecommerce space for a number of years I see this particular layout come up very often. We’re going to focus on a category listing of products. On large screens we’ll display three products per row and we’ll move that number down as the viewport gets smaller.
If we were doing this with inline-block
our Sass would look something like
this (view
demo):
.products-grid {
font-size: 0; // inline-block hack
@media screen and (min-width: 600px) {
margin: 0 -0.5rem; // hack to stretch our products to fill the container
}
}
.products-grid-item {
font-size: 1rem; // reset inline-block hack
text-align: center;
@media screen and (min-width: 450px) {
display: inline-block;
width: calc(50% - 1rem);
margin-top: 2rem;
padding: 0 0.5rem;
}
@media screen and (min-width: 900px) {
width: calc(33.33% - 1rem);
}
@media screen and (min-width: 1200px) {
width: calc(25% - 1rem);
}
img {
display: block;
width: 100%;
}
}
It’s not the worst bit of code that we could write but it’s littered with comments that actually use the word “hack” in it. We’re using a feature for CSS in a way that it wasn’t really designed for. This is where CSS Grid Layout comes into play.
Our Grid: The Redux
CSS Grid Layout is very powerful and is capable of creating incredibly complex
layouts. We only need a few basic tools in order for us to convert our
inline-block
layout, though.
display: grid
– this is the new display value that will enable us to use all that CSS Grid Layout has to offer.grid-template-columns: <values>
– this will allow us to define how many columns we would like our grid to display our products in.grid-gap: <values>
– this is the shorthand for settinggrid-column-gap
andgrid-row-gap
and will let us define the space between our products.
Those are the only three features that we need in order to get started with CSS Grid Layout! Our Sass now looks like (view demo):
.products-grid {
display: grid;
grid-template-columns: 1fr;
grid-gap: 1rem;
@media screen and (min-width: 450px) {
grid-template-columns: 1fr 1fr;
}
@media screen and (min-width: 900px) {
grid-template-columns: 1fr 1fr 1fr;
}
@media screen and (min-width: 1200px) {
grid-template-columns: 1fr 1fr 1fr 1fr;
}
}
.products-grid-item {
text-align: center;
img {
display: block;
width: 100%;
}
}
While we haven’t dramatically reduced the number of lines required to create our layout, we’ve reduced the complexity and we’ve made our code significantly more explicit about what it’s trying to accomplish. Let’s go through these new additions one by one.
display: grid
This is necessary for the rest of the styles to function. On its own display:
grid;
will make no changes to how the content is displayed. You can think of it
like a flag you can turn off/on to enable the rest of the element’s styles (just
like flexbox).
grid-template-columns
This is one of the most confusing parts of CSS Grid Layout because it introduces
a new value which I’ve used above: fr
. W3 defines the unit like this:
A flexible length or
is a dimension with the fr
unit, which represents a fraction of the free space in the grid container.
This works a lot like flex-grow: 1
when using flexbox. In our case, 1fr
means “one unit of space of the total number of units”. So if we had our column
values as 1fr 2fr 3fr
our first column would take up 1/6 of the remaining
space (space after all grid-gap values are taken into account).
grid-gap
Here we’re setting our gutters to be 1rem
both to the left/right and
above/below our products. What makes this so much better than using padding or
margin is that this gutter will only appear between our products. This means
we don’t need any special rules to remove the gutter where it isn’t needed (like
the above the top row or below the bottom row).
Browser Support
I’ve got some good news and some bad news.
The good:
- unprefixed support is coming in the next releases of Firefox (52), Chrome (57), Safari (10.1), and Opera (43)
The bad:
- Microsoft Edge is still shipping with the IE11 implementation which uses an old version of the specification
2017 will be the year of CSS Grid Layout!
What’s Next?
This is just a tip of the iceberg of what CSS Grid Layout can provide. While the example above doesn’t utilize all of the features available to us it should give you a taste of what’s possible. Feel free to fork the examples and see what other creations you can create.