The New CSS Layout, An Excerpt · An A List Apart Article

As we have seen, flexbox wasn’t designed for grid layouts—but this is where our newest specification is most at home. CSS Grid Layout does exactly what its name suggests: it enables the creation of grid layouts in CSS. This is two-dimensional layout—laying things out as a row and a column at the same time. We’ll go over many more examples of Grid Layout in the rest of this book, but let’s start by seeing how Grid can solve the problem we had with making flexbox display like a grid.

In this example, I’m creating a three-column grid (Fig 3.17). My container has display: grid, and I’ve created three equal-width columns with the grid-template-columns property, plus a new unit created for Grid: a flexible-length unit known as fr. We’ll take a closer look at this unit in Chapter 5; for now, keep in mind that it represents a fraction of the space available in the grid container. With three tracks all set to 1fr each, the available space is divided into three and distributed equally. This is all we need to do to get the direct child of the container to display as a grid. Unlike with flexbox, we don’t need to add any rules to the children; they will just pop themselves into each cell of the grid.

As you can see, the items form a strict grid, without us needing to set any widths on them. We can solve another issue that we have with creating a flexbox grid, using properties that are part of the Grid specification. To create gaps between our flex items, in our flexbox example we used margins on the flex items and then needed to add a negative margin on the container to account for the unwanted left and right margin on the far left and right items. CSS Grid Layout includes a grid-gap property to space items out. This property is shorthand for grid-column-gap and grid-row-gap, which can also be specified individually.

To demonstrate how this works, I’ve removed the margins on the items and the negative margin on the container and spaced the items out with grid-gap. You’ll produce the exact same layout as above in the browser, but without the need to mess around with margins and negative margins.

Just as this book was going to print, the CSS Working Group resolved to change the name of the grid-gap properties. grid-column-gap will become column-gap, grid-row-gap will become row-gap, and the grid-gap shorthand will simply be gap. In addition, the definition of these properties has been moved to the Box Alignment Specification. This means that in the future, flexbox may also support gaps in the same way as Grid.

Because browsers have already shipped these properties, they will alias the grid-* names to the new names for the foreseeable future. At time of writing, no browser supports the new property names, so I’ve retained the grid-* versions in these examples. If you want to be sure of supporting both versions, there’s no reason not to list both in your CSS, as in this example:

Positioning items around the grid

We can quickly move away from what flexbox allows us to do by taking advantage of our two-dimensional grid and positioning items on it. The most basic way of doing this is by using line numbers. A grid has numbered grid lines; they start from 1 for both rows and columns. Note that these lines are numbered per the writing mode of the document. Working in English, a left-to-right (LTR) language, column line 1 is on the left-hand side of the grid; row line 1 is at the top. In Arabic, a right-to-left (RTL) language, column line 1 appears on the right of the grid. The far edge of the grid (right in a LTR language and left in a RTL language) is represented by -1.

You can immediately see some of the power of Grid Layout here. We can span columns and rows—something that is hard to do using existing layout methods. The background color of our cards extends to the gutter, even if the content is shorter. It’s also very easy to change how far a block spans—we can even leave white space! If I change the start line of card 3 to row line 3, we get an empty cell (Fig 3.19). Nothing can rise and land in the grid cell; this differs from the behavior of floats, which try to float up and fill the available space.

Fig 3.19: White space made easy with CSS Grid Layout.

Another method of positioning items on a grid involves using named areas. This allows you to describe your layout right in your CSS. To do this with our example, we first give each card a name with the grid-area property. I’m just using letters a through e.

There are a few things to keep in mind with grid-template-areas. To span across cells, we repeat the name of the area. Card 1 spans across the first two column tracks; thus a is repeated. The areas must be rectangular in nature—we can’t yet create an L-shaped area.

To leave white space, and to leave a cell empty, use a full-stop character. If you replace the first c with ., that cell will remain empty when the layout is created (Fig 3.21).

If your grid-area names are longer than one character, you may want to line up the visual rows and columns in the value of grid-template-areas. This is possible because more than one full-stop character can denote an empty cell—if they have no white space between them. You can also add more than one white-space character to space out grid-area names.

This is a very nice way to work with layouts, given how easy it is to move items around. I enjoy working like this during the prototyping stage—rather than worrying about how to achieve layout, I can figure out the best way for my interface to be presented. Then I can go back to the markup to make sure it’s in a logical order based on those decisions.

With these few examples, you already have enough knowledge to start using Grid Layout, and to make decisions about which layout methods to use. There is more to come, but keep in mind that although the specification is large and can do a lot of things, it is very simple at its core. You can do a lot with very little CSS. As you start building layouts, you will have questions, and will want to achieve more with these layout methods. That’s where the rest of this book comes in!