Simplify Your Layout (And Your Life) With CSS Grid
How emerging web technologies enable new ways of approaching design and layout
Over my career as a web developer, I’ve written my fair share of CSS layouts — from common websites through business tools to messenger applications. And most of the time, it has been an endless pit of despair, a teeth-falling-out nightmare, the bane of my existence!
Okay, maybe I’m being a bit dramatic, but have you ever found yourself stuck for hours trying to get an element to center vertically, expand to fill its container, or fit properly on smaller devices? If you have, then you probably share my sentiment — doing layout in CSS is really hard.
Or, at least, it used to be — until I learned about CSS Grid. But to show you the new way, let’s first go through what I used to do before…
Behold the villain
I’ve had to write this specific layout multiple times — a header, a sidebar, and some content. For the purpose of this post, let’s call it HSC:
When I first started with UI development, my weapon of choice for this was absolute positioning — it’s straightforward math where you work with coordinates:
Logically, the sidebar and content start where the header ends — at 75px from the top. The sidebar takes up 350px on the left side, and the content starts from that point all the way to the right.
It’s not too bad — until you decide to adjust the height of the header or the width of the sidebar, and realize you also have to change it in a bunch of other places. Of course, this issue is easily solved by using CSS variables or a scripting language like SASS:
Here’s the final result where I’ve replaced all hardcoded values with variables:
But even with the help of variables, any time you want to make changes, you have to start calculating coordinates again. Consider how you would add a new element to that layout —you’d have to consider the top, right, bottom, and left positioning of all other elements, and adjust accordingly. Heaven forbid you wanted to add a 10px gap between all the different areas, or conditionally move or completely remove certain elements on smaller resolutions.
What about Flexbox?
When all major browsers finally added official support for the CSS Flexbox spec, many companies adopted it, and some even shipped it to production. I, for one, welcomed our new Flexbox overlords, and was quick to proclaim the end of all my CSS woes.
It was great for a while, and I would use it for anything — from building the perfect vertically-centered menu to positioning avatars, chat messages, and buttons inside a card.
However, as far as the hallowed HSC layout was concerned, it actually felt more uncomfortable doing it the new (supposedly better) way:
No, no, no, I’m not even getting into this — 2 wrapper elements just to use Flexbox?
Use the Grid, Luke
I had heard of CSS Grid before, but it wasn’t until I stumbled upon this talk that I really started paying attention:
Basically, CSS Grid allows you to split a container into rows and columns and define how its children should fit inside. Instead of thinking about the coordinates of individual elements, you can now think of the behavior of their parent.
table all over again either, because you don’t need special tags like
td to create rows or columns — the DOM can remain flat if you want it to.
Here’s how you could rewrite the HSC layout with CSS Grid:
grid-template-rows: 75px auto;
grid-template-columns: 350px auto;
After defining the rows and the columns of the grid, you place each element in its appropriate cell:
- Header — row 1, columns 1 to 3 (excluding 3, meaning columns 1 & 2; alternatively, you can write
- Sidebar — row 2, column 1
- Content — row 2, column 2
And, if your browser supports it, it should look exactly the same way:
If you open the developer tools, your friendly neighborhood browser might even show helpful lines to indicate how exactly the grid is distributed. I’ve gone one step further and annotated the row & column of every cell in yellow for you:
This way, you stop thinking about coordinates and start thinking about your application in terms of different areas. And if you do need to adjust the size of the rows and columns, you can do so in a single place — the container element:
grid-template-rows: 100px auto;
grid-template-columns: 400px auto;
There’s something even cooler that CSS Grid allows you to do — instead of placing your elements at specific rows and columns, you can assign a named area to each one:
grid-template-rows: 75px auto;
grid-template-columns: 350px auto;
grid-template-areas: 'header header '
This extremely visual, almost ASCII-art-like way of describing your layout, makes it very intuitive to move stuff around.
How about making the header only span 1 column, with the content spanning both rows, like this:
grid-template-areas: 'header content'
What if you wanted to make the sidebar take up both rows in the right column:
grid-template-areas: 'header sidebar'
Check and mate. We only had to switch
On a scale of 1 to 10, how cool is that?
If you’d like to play more with this design, here’s the pen:
Perhaps you’ve noticed that in the collection of pens I showed you in this post, I’ve also implemented a responsive version of the design, better suited for mobile devices:
Here, the sidebar is hidden to the left, giving way to the content. If we need the sidebar, we can expand it by tapping the > button in the top left corner (also commonly known as the hamburger menu, and portrayed as ☰).
You can judge for yourself what the pros and cons of using CSS Grid for responsive design are. In this case, it seems to me that rows and columns work better than grid areas.
According to the spec, CSS transitions should work on
grid-template-columns. However, I was unable to get a sweet animation when transitioning the sidebar and content between the wider and narrower responsive designs. Animation worked just fine with the absolute positioning approach.
While most modern browsers support the spec well, older versions of the Android browser don’t, and IE has implemented a previous version of the specification that differs significantly.
A great design tip I stumbled upon was that you should start with a linear, mobile-first layout, then incrementally improve it for larger resolutions using CSS Grid. If the browser doesn’t support it, then your website safely falls back to the already great-looking linear design!
Overall, you should consider what your users’ devices are before completely switching to grids. Be smart, don’t just fall for all the hype I’m selling you 😉
There’s a ton more you could do with CSS Grid, like define multiple rows and columns at once using
repeat, use grids within grids (gridception!), and even add gaps between cells:
So, congratulations — if doing layouts in CSS was really hard before, with
display: grid it's now just hard 😐
But wait, what do you think? Is CSS Grid going to solve our most pressing layout troubles? Or become the next proverbial hammer where every problem looks like a nail? Or is it just an overhyped fad that doesn’t really change things all that much? Your move.