The CSS Grid Layout Module — Flexible Structures for Content

I often suggest that designing with a grid is a good idea. Developing them in html and css sometimes feels like a hack, though. Developers certainly build grids for use online and there are a variety of frameworks you can use that do the work for you. Still, wouldn’t it be nice to have some native css for creating grids?

That native css is on its way in the form of the CSS Grid Layout Module. Browser support, while hardly great, is a little better than I expected. IE10+ supports grids with the -ms prefix and Chrome Canary supports them by enabling the experimental web platform features flag. Other browsers lacked support, but seemed aware of the grid code I used, giving hope support will come soon.

There’s quite a bit to cover in regards to css grids so I hope you don’t mind if I split this post in two. Today I’ll walk you through working with css girds. On Thursday, I’ll provide examples of code in practice.

CSS Grids

CSS grids offer the ability to develop a real grid in which to place content. They create a mechanism to divide the available space into columns and rows. In some respects they come with the benefits of tables without the downsides of tables.

There are some basic terms we should know when working with css grids. These are defined below and are shown in the image above.

Grid tracks — are a generic term for grid columns and grid rows

Grid lines — are the horizontal and vertical dividing lines of the grid. They exist on either side of a column or row

Grid areas — are the space used to lay out one or more grid items. A grid area is bound by 4 grid lines.

Grid items — are the elements and content we place inside the grid.

Grid Layout Box Model

To create a css grid you set the display property of an element to grid or inline-grid.

[code type=css]
display: grid | inline-grid;
[/code]

A value of grid generates a block-level grid container and a value of inline-grid generates an inline-level grid container.

Either creates a new grid container, which establishes a new grid formatting context. Floats won’t intrude into the grid container. and the margins of grid containers won’t collapse with their content.

The content of a grid container can consist of zero or more grid items and grid items can form new grid containers (subgrids) to have one grid inside another.

Defining Columns and Rows in a CSS Grid

The first property for working with css grids is the display property and as we saw above you want to set the value of display to grid or inline-grid.

Once you’ve created the grid container you need to define the grid you want to use and you’ll do that with the following 2 properties.

[code type=css]
grid-definition-rows: none |grid-definition-columns: none |[/code]

The value none isn’t particularly interesting so lets focus on track-list, which is essentially a sizing function. You set one or more values, each representing some kind of size representing the length or height of the columns or rows.

[code type=css]
grid-definition-columns: 100px 100px 100px
grid-definition-rows: 50px 50px 50px
[/code]

The css above would create a 3×3 grid with columns 100px wide and rows 50px deep. The values of each column and row don’t need to be the same and you don’t need to use px. You can use px, em, %, or any other unit of measurement.

There are also some grid specific measurements you can use defined below.

flex (1fr, 2fr, etc) — If you’ve worked with flexbox this should be familiar. Once the non-flexible measurements are distributed, each flex value is a share of the remaining free space. If 2 columns have 1fr and 2fr respectively, the first would get 1/3 of the remaining free space and the latter would get 2/3 of the space.

max-content — the largest max size contribution of the grid items.

min-content — the largest min size contribution of the grid items.

minmax (main, max) — defines a size range greater than or equal to min and less than or equal to max.

auto – computes to minmax(min-content, max-content).

We can give meaningful names to grid lines to make them easier to work with.

[code type=css]
#grid {
display: grid;
grid-definition-columns: “first” “nav” 150px “main” 1fr “last”;
grid-definition-rows: “first” “header” 50px “main” 1fr “footer” 50px “last”;
}
[/code]

The code above creates a 2 column, 3 row grid. The first column grid line can be referred to as either first or nav, the second as main, and the 3rd as last. Similarly the 4 row grid lines are first/header, main, footer, and last. Dimensions are set in between these reference names.

repeat() notation

If your columns or rows repeat in size you don’t need to specify them all individually. Instead you can use the repeat() function to keep things DRYer.

[code type=css]
grid-definition-columns: repeat(4, 10px “col-start” 250px “col-end”) 10px;
[/code]

Setting Grid Items

We’ve seen how to define grids, but so far those grids are empty. How do we tell content to live inside our grids and where? You do that by setting grid-column and grid-row properties with the values of those properties being an integer representing a grid line.

[code type=css]
#content {grid-column: 1; grid-row: 2;}
[/code]

The css above tells the element with the id of content to locate itself in the first column of the second row. You don’t have to use an id as the selector. Any element, class, etc. will work.

Named Areas (grid-template)

Another way to tell content where it should live inside the grid is by creating named areas through the grid-template property.

[code type=css]
grid-template: none | +
[/code]

The string value allows us to name each grid area and show where each should be located in the grid. This is easier to see with a real example.

[code type=css]
grid-template: “first second third”
“fourth fifth sixth”
[/code]

The above could be used for a 3 column, 2 row grid. The three areas on the first row are named first, second, and third respectively and the areas in the second row are named fourth, fifth, and sixth. Note that areas are separated with a space and a new row is indicated by a new set of double quotes.

To set content in these areas we hook into the identifiers above.

[code type=css]
#first {grid-area: first}
#second {grid-area: second}
[/code]

and so on.

Named areas are a nice way to quickly see what content belongs where in the grid, because your code essentially recreates your grid visually.

Grid Placement Properties

Another way to place grid items and it’s through the grid-placement properties

grid-before

grid-start

grid-after

grid-end

In your css you would include the dimension (column or row) in each of the properties as shown below.

[code type=css]
#content {grid-column-start: 2; grid-column-end: 3}
[/code]

The above would place #content between the second and third column grid lines. Instead of an integer value you could use a named area. You can also tell a grid item to span a certain number of columns or rows.

[code type=css]
#content {grid-column-start: 1; grid-column-end: span 2}
[/code]

The above would start #content in the first column and have it span a total of 2 columns. Below is a shortcut for writing the same thing.

[code type=css]
#content {grid-column: 1 / span 2}
[/code]

Auto-Generated Rows and Columns

One of the things I worried about when I began experimenting with css grids, was that we’d need to know in advance the size of grid-items, grid-areas, etc. That would make it difficult to use css grids for anything where the amount of content on the page might vary. For example I have no idea how long my next blog post will be, but the design for that post is done.

Fortunately I didn’t need to worry. Rows and columns can be auto-generated to allow them to be resized based on how much content is placed inside of them. You do this simply by not setting a size.

[code type=css]
grid-definition-columns: 100px 100px 100px

grid-template: “first second third”
“fourth fifth sixth”
[/code]

In the code above column dimensions are set, but no row dimensions have been specified. The two rows that are created with grid-template are auto-sized based on the content they contain.

Some Additional Grid Properties

There are a few more properties for working with grids, though I’ll simply touch on them briefly and refer you back to the spec for more details.

Automatic Placement

Grid items can be automatically placed into unoccupied areas in the grid container through the grid-auto-flow property.

[code type=css]
grid-auto-flow: none | rows | columns
[/code]

Alignment

By default grid items stretch to fill their grid area, but you can change that alignment. The properties below might look familiar to you if you’ve played around with flexbox.

justify-self

justify-items

align-self

align-items

Z-Axis

Using the alignment properties above can cause several grid items to overlap each other and you can use the z-index property to determine which grid item(s) display on top of others.

Summary

Grids offer a lot of benefits for structuring your design, but they haven’t always been easy to develop with css. It’s one of the reason some people hold on to table-based layouts or use of css tables.

CSS grids will make it much easier to develop the grids we design. Browser support isn’t there yet, though it seems to be gaining traction. For now you’ll need to use IE10+ (with the -ms prefix) or Chrome Canary (no prefix, flag set).

I realize a lot of properties are mentioned in this post, but I promise css grids are easier to use than all those properties seem to indicate. Many of the properties I walked through above are just different ways for doing the same thing.

After setting the grid container through the display property, there are basically two sides to working with grids and a variety of ways to work with each. One side defines the grid itself. The other side sets how content should be positioned inside that grid.

On Thursday I’ll walk you through an example or two. Hopefully any confusion I might have created here will go away once you see some real code in action.

Download a free sample from my book Design Fundamentals.

Join me as I share my creative process and journey as a writer.