Development

Get on the Grid at Last with the CSS Grid Layout Module

7 Apr 2017 10:26am, by

How weird is it that Cascading Style Sheets (CSS), the universal styling language of the web, has always been fundamentally broken when it comes to layout?

Since the earliest days of breaking out style from markup, web developers have struggled to put things where we want them to go and, even better, have them stay there. There has never been a reliable tool or effective system for this. In the early days, we forced table markup to do layout duty — even though it was never intended for that. Eventually, the float property came along; it was another not-meant-for-layout tool that desperate devs could use, together with clear, for creating some semblance of a layout. Then came official CSS positioning, an entity actually intended for layout but unfortunately never built out well enough to do it effectively (shudder clearfix shudder).

CSS gradually grew powerful enough as a language to achieve all kinds of effects on the page, even complex and vivid animations — but layout languished and devs simply hacked together whatever worked. Most recently Flexbox has made our lives easier, and as a web dev, I am actually pretty happy with Flexbox. I have been able to get it to do what I need it to do, more or less, most of the time, which is more than I can say for all previous contenders. There is always room for improvement, though, and so I — along with the rest of the web dev world — have been waiting impatiently for the CSS Grid Layout Module to finally go live.

It was a long time coming. The specification was first proposed in April of 2011, by Microsoft, as “CSS Grid Layout.” Early versions were included in Internet Explorer (versions 10 and 11) and the spec was adopted by the World Wide Web Consortium (W3C) as a working draft in 2012. Volunteer editors from Mozilla and Google joined Microsoft in refining and developing the specification over the next five years. Finally, in March 2017, the CSS Grid Layout Module went fully live and is now appearing in a browser near you. Grid is now supported in recent versions of all the major desktop browsers, and in iOS Safari and Chrome for Android mobile browsers.

And I, for one, could not wait to get my sticky little web dev fingers on this new toy. Which from here on out we will refer to as “Grid.”

When playing around with new projects I often use glitch.com for ease of use and instant gratification of live web display, but unfortunately glitch did not seem to sprechen sie CSS Grid, even in Chrome’s Canary browser with “experimental Web Platform features” turned on, so I bailed on over to Atom and good ol’ localhost:8000 to mess around with it locally. Grid worked for me in Chrome v.57 with no flag necessary, despite the warnings in the caniuse.com current state of affairs summary for Grid.  Encouragingly, the Atom text editor offers Grid properties as an autocomplete in the editor, so it was nice to know I’m not in entirely uncharted waters here.

It’s Kind of Like Legos

Yes, Legos. In that, with Grid, we are stacking and connecting together boxes of various shapes and sizes to (hopefully) build a smooth, even whole. First, we make some basic boxes in HTML:

Then the CSS Grid fun starts with display: grid; (just the way flexbox layout starts with display: flex;). Once this is established on the parent container, it’s time for fun with rows and columns. The CSS Grid Layout Module provides two properties for accessing them: grid-template-rows and grid-template-columns (which Atom also helpfully provides in a popup):

This establishes three 100px columns, separated by two 10px gutters. The grid-template-rows line established three rows; the center one is again a 10px gutter. The other two are “auto” — a beautiful thing meaning that they will expand to hold whatever content is stuffed inside. Here is how it looks:

Wait, whuuuut? Ohhhhh: The problem is that the Grid children have obediently attempted to place themselves in order of markup within the provided columns, meaning that some have crammed into the 10px gutter columns. Even though there remain content columns, empty and available.

Happy Little Boxes

The fix for this auto-placement phenomenon also happens to be Grid best practice: designated positioning of each item within the Grid, which relies on line-based placement for layout. The properties look like this for our first happy little box, A:

That is a lot of typing, so, fortunately, Grid throws in some shorthand:

Wherein grid-column and grid-row values represent column/row start and column/row end.

Since we probably also want to do some other stuff to our happy little boxes, CSS Grid Layout Module has an even shorter shortcut: the grid-area property.

This consolidates the start and end values for both rows and columns into one neat line, but — for me, at least — the convenience is offset by a loss of readability. It’s early in the game, true, but for now, I’ll be going with the middle road, grid-column and grid-row.

So, our CSS — now with custom box placement! — looks like:

(And, oh yeah, I snuck in some more formatting because, well, boxes.)  Anyway, we went from elements disappearing into gutters when the boxes log-jammed due to Grid’s default placement:

To a nice, neat —  wait for it — GRID!

Buuuut since it’s no longer 2001, we probably don’t want a landscape of small square content boxes in our web apps, right? Grid understands. Grid groks our design needs and responds by being kind of infinitely elastic. A Grid box (area) can be ANY dimension that fits within the initial grid declaration of rows and columns. We merely need to specify content start and endpoints.

So here’s the same grid declaration, now with four differently-dimensioned boxes. Starting to look like an actual layout, even:

Note that, within Grid, the markup order of these Grid child elements does not matter. Which is cool: We can do the right thing syntactically in HTML, and then place those elements independently from source order, however, we want in CSS.:

(Interestingly, you can have boxes overlap in Grid. Below, A now spans the entire 5 columns, with B overlaying in the grid-column: 5/6; the area they both share. Since this is CSS, that probably will result in some terrible and unanticipated results further down the line, but I am still tucking this info nugget in my back pocket to play with later. Because you never know when it might come in handy design-wise. Caveat lector.)

Lingo Time!

Our next steps with the CSS Grid Layout Module are going to require some new vocabulary.

Horizontal and vertical GRID LINES make up the grid. The default way to access these is by number, but they can also be assigned a name.

A GRID CELL is the space between any four intersecting grid lines and is the smallest unit in the CSS Grid system. Sort of like a single table cell in a spreadsheet.

A GRID AREA is made up of multiple grid cells. It must still be bound by four grid lines. (So we are talking squares and rectangles here, but not “L” shapes).

GRID TRACKS are the spaces between pairs of vertical or horizontal grid lines. In our example, we have broad grid tracks representing spaces where content would go, and narrow grid tracks that function as gutters.

For now, gutter spaces between grid areas must be manually planned and placed. I can foresee that keeping gutters in mind when naming grid lines is going to be kind of a pain in the ass. There are forthcoming Grid properties called grid-column-gap and grid-row-gap to help with the process, but they are as yet not widely supported across the browser-verse. Until they are, Grid gutters are strictly DIY. But I think you can handle it.

And Now: The Power Up

By this point, Grid seems maybe kinda cool if all you want to do is lay out table variations. “Meh” is an understandable response. But wait — there’s more!

The CSS Grid Layout Module delivers a built-in method for quickly creating and auto-positioning common website components like sidebars and footers. It’s a property called grid-template-areas, which places named grid areas in the places we’d think they would generally go. Let us start with the simplest of HTML markup: a header, a footer, some content, and a sidebar:

To style this into something resembling a page, we begin the same way as before by establishing the grid. First, declaring display: grid on our wrapper and then defining grid-template columns and grid-template-rows. This time I threw down seven columns — four content, three gutters — and stated dimensions in (more-responsive) 12.5em/1em units instead of pixels. And went full auto with rows, just to see what would happen.

Now the magic happens: grid-template-areas. To define what we want going where, CSS guru Rachel Andrew makes the very apt comparison to making ASCII art: you have to type the element name once per slot that you want it to fill. Since we have seven columns across, and header goes on top, we start with “header header header header header header header.”

For content and sidebar, content gets more play because sidebars, well, go on the side: “content content content content content . sidebar.” Which is Grid-speak for “make the content five columns wide, leave the sixth column empty, and allot one column to the sidebar.” The period character tells Grid to leave that grid cell empty.

Notice there are no horizontal gutters because we did not declare any in our grid-template-rows. There is one vertical gutter, thanks to the “.” in the second row of the grid-template-areas values statement.

Another cool thing: you can use Flexbox inside of Grid child elements! I wanted the “some side stuff” text inside the sidebar grid area to be centered vertically and horizontally, rather than the default block. So by declaring display: flex on .sidebar we are able to use the align-items and justify-content Flexbox properties to center the sidebar’s text content.

The Upshot

So this is the basic get-up-and-running info you need to jump in and start messing around with the CSS Grid Layout Module for layout. There has been much hype about how this at long last is the Holy Grail of CSS layout tools, but so far I remain unconvinced. While I have much more to learn before gaining Grid Guru status — and it is possible that unanticipated-by-me marvels lie ahead —  fundamentally this is a grid system.

Though I have to say it’s nice to hope that the advent of Grid means, at the very least, we may never have to float anything, anywhere, ever again.

A newsletter digest of the week’s most important stories & analyses.