I always get so excited when I see much needed features planned for release in the front-end world. And then I immediately get a little sad — because it takes so long for them to finally become practical to use.
The problem is that these many future changes are quite a mission to keep track of… and so it comes down to a chance encounter or a memory suddenly popping up or a keen colleague reminding me to have another look.
That’s exactly what happened to me with CSS Grid… and also why I’m writing this article.
A bit of history
If you’ve been around the frontend world for any length of time you’ll know how much we’ve needed a decent grid solution. In the previous century (and maybe a little too much of this one), we shoehorned everything into tables.
Then, with the wider acceptance of CSS and the semantic web, we managed to get
<div> s, CSS floats, negative margin-foo, and absolute positioning to work together in some kind of Mad Hatters layout party.
A number of grid libraries have tried to provide solutions for this layout issue, but for the most part, these have been the jury-rigged, CSS-class-heavy fixes that they could only ever be.
Next came Bootstrap and Foundation. Two CSS frameworks that incorporated base components, icons, and a grid, but it was all still rather constraining, with an over-reliance on heavy class-name usage and heavier framework resource downloads.
When Flexbox hit the CSS world, I sensed a glimpse of better things to come. Was CSS finally moving in the direction of assisting with real-world layouts without needing a 3rd degree rank in the Masons to get it right?
Flexbox has paved the way for CSS Grid, which borrows a lot of the naming-conventions, parameters, and logic first introduced with the flex feature-set.
Enter CSS grid.
Personally, I’d almost forgotten about CSS Grid — having become drawn deeper into the world of JS frameworks React and Angular over the last few years, where we seem less and less concerned with the nitty-gritty world of HTML and CSS layout.
I found myself spending my time solving development problems and rather sticking to the CSS tools and methods I knew and loved (or begrudgingly tolerated) — they got the job done.
So, when a colleague suggested I take another look at CSS Grid, I was pleasantly surprised upon checking CANIUSE, to find this:
CSS Grid is essentially usable across all the major browsers and as a result, I’ve dived headfirst into upskilling myself and we will be pushing for its use (wherever it is relevant) at NONA moving forward.
So, you may ask, “why should I care?”
Well, in short, it’s a pretty damn fantastic layout solution. Since the birth of the web, we've always had to struggle with actually laying out our websites, forcing things to fit and be used in ways that they really weren’t made for.
Even flex is only partially useful for grid-type layouts. It absolutely shines as a single-direction layout tool (vertical or horizontal) — and does have a wrap, but it’s really quite limited when it comes to grid-based layouts, especially when compared with CSS Grid.
When it comes to multi-dimensional layouts, CSS Grid, once you get the hang of it, is an absolute dream.
Some benefits of using CSS Grid:
- It is trivial to create any number of columns. 5, 6, 88.. it doesn’t matter — just define your columns and rows and the browser’s CSS engine will make the magic happen!
- The fr (or “fraction”) unit makes it really easy to build out layouts that expand by default to their containers while maintaining the column or row ratios you’ve defined. Each defined fr will became a fraction of the overall layout. So 1fr 1fr 1fr will create a 3-column grid where each column is the same size (33% per column). 1fr 2fr 1fr, will also create a 3-column grid, but the second column would be double the width (50%) of the first and the last columns (25% each).
- The repeat() function. The repeat function takes 2 arguments, the number of times to repeat, and the thing you want repeated.
grid-template-columns: repeat(3, 1fr);
This does what I’m sure you’ve already figured out, repeats your second argument the n-number of times set in your first argument. In the example above, that would be 1fr repeated 3x or the equivalent of the rule:
grid-template-columns: 1fr 1fr 1fr;
Read more about the repeat function on MDN.
- Only define the rows and columns you want to. Grids by default continue to follow a normalised (and easily defined) flow when continuing outside of the presets you’ve created -this allows you to create a set of defined rows, and then everything else will just flow after that.
- You can name areas of your grid — and then place your cells into those areas — making templating so trivial it’s laughable.
- Grid Lines. CSS Grid introduced grid-lines — essentially the lines that form the mid-points between the cells. These can also be named, paving the way for really advanced grid layouts and templating.
- The minmax(min, max) function. The minmax function defines a size range greater than or equal to min and less than or equal to max. I’ll be diving deeper into this in a later post, but for now, you can read more on the Mozilla developer site.
Getting the hang of it.
One of the slight downsides with CSS Grid is, to bastardise a cool quote:
“With great power comes a little more complexity.” It’s definitely one of the most complex of all the CSS features to date.
There are more than a few new concepts that need to be absorbed (the idea of grid lines), some old ones revisited (when last did you use a span to span multiple columns in a table — …anyone?), some ‘new’/adjusted units (fr (fractions) work very similarly to flex’s item: 1 or 2) and at least 2 new CSS functions.
But all-in-all it’s absolutely worth taking the dive and making CSS Grid part of your CSS toolset.
Getting started with a basic grid
To get started on a basic grid, you need three things.
- Define your grid.
With CSS Grid, this is super-simple and uses the current
displayproperty. Simply set it to ‘grid’ and you’re done!
- Define your columns.
Defining columns is done by telling the grid how many columns you want. You do this by defining a width for each column using the grid-template-columns property, eg:
grid-template-columns: 100px 100px 100px;
This would create a 3-column grid with each column being 100px in width. As you can imagine, this can get a bit tedious to write out, so to make our lives easier, we can use the repeat function along with the fr unit to make sure it scales responsively.
- Mind the gap. (optional)
The third thing you’d want to set, although it really is optional, is the gap or spacing between your grid items. This is set with the shorthand grid-gap property. It takes the grid’s row gap first and the column gap second. As with other CSS shorthand properties, setting a single value sets them both to the same value. You can set each one with separate properties if you wish, using grid-row-gap and grid-column-gap respectively.
That was a lot of words for 5 lines of code.. but here’s it all put together:
Where to from here?
As is probably obvious, we’ve only scratched the surface of all things CSS Grid, so this will be the start of a series of articles as we take a deep dive into all it has to offer and solutions to some commonplace and previously tough layouts.