CSS Grids: Examples and Code for Common Layouts

Earlier in the week I walked through the css grid layout module. There was a lot to cover and as the post grew long I saved some real examples for today.

As a quick reminder browser support for css grids is limited. They should work in IE10+ (with the -ms prefix) and I was able to get them working in Chrome Canary (without any prefix), by enabling the experimental web platform features flag. Other browsers seemed to be aware I was using grid code to some degree, but none of those I tried actually displayed the grid.

Because browser support is limited, instead of linking to a demo, I’m showing a screenshot for what I created and will detail the code used to create it below. If you haven’t yet experimented with css grids, I suggest reading my post from earlier in the week. The examples below assume you’ve either read it or are familiar enough with the spec to allow me to rush through a few details below.

3 column, 6 row grid created with named areas in css

CSS Grid Example 1

The image above shows what might be a typical layout for a web page. It’s a 3 column grid, which you can see with the asides toward the bottom. The navbar, header, and footer span all 3 columns and the main content area spans 2 columns. The html is fairly simple. It’s a bunch of divs inside a container div.

[code type=html]

Navigation Bar

Header

Main Content

Sidebar

Aside 1

Aside 2

Aside 3

Footer

[/code]

You don’t have to assign everything an id as I did here. I could just easily have used regular html elements classes, attribute selectors, simple combinators, pseudo classes or whatever I wanted to use for the css selectors.

I’ll skip over some of the generic css I used to center things horizontally and give background colors to the different grid items. I’ll assume that’s routine for you.

To create the grid I first created a grid container by setting the display property of the #grid div to grid. Next I defined the grid itself, by giving values to the columns, rows, and named areas.

[code type=css]
#grid {
display: grid;

grid-definition-columns: 1fr 1fr 1fr;
grid-definition-rows: 40px 150px 1fr 1fr 1fr 50px;

grid-template: “navbar navbar navbar”
“header header header”
“sidebar main main”
“sidebar main main”
“aside1 aside2 aside3”
“footer footer footer”;

}
[/code]

The grid is 3 columns wide and 6 rows deep. Each column is 1fr (1 fractional unit) wide, meaning the space will be divided equally among them. I could have specified 33.333% for each, or even specified that percent on one of the columns leaving the other two at 1fr and it still would have been the same.

With the rows I decided to fix the height for the navbar, header, and footer, and then let the other 3 rows divide the remaining free space equally.

As you can see I decided to position the grid items through the use of named areas assigned to the grid-template property. I’ll show you an alternate way to position the grid items in example 2. I like the visual presentation that named areas offer as you can look at the grid-tempate value and quickly see where everything is supposed to be in the grid.

As I mentioned on Monday there are two sides to working with css grids. The first is defining the gird and the second is to set the grid items inside. We defined the grid above. Let’s place things inside of it.

[code type=css]
#navbar { grid-area: navbar; }
#header { grid-area: header; }
#main { grid-area: main; }
#sidebar { grid-area: sidebar;}
#aside-1 { grid-area: aside1; }
#aside-2 { grid-area: aside2; }
#aside-3 { grid-area: aside3; }
#footer { grid-area: footer; }
[/code]

The above should be mostly self explanatory. All I’m doing is mapping each div from the html to a corresponding named area. While I’m using the the same, or similar names for both in this example, there’s no reason you have to. #navbar could have been mapped to grid-area: area-51 had I decided to call one of the named areas, area-51. The names of the named areas are arbitrary, though I would suggest trying to use meaningful names where possible.

One extra bit of css I had to add for this example was the following.

[code type=css]
div {height: 100%}
[/code]

Without setting a height, the divs collapsed vertically to the size of the content within them. It’s not something you would typically need, but here with little content and wanting to fill up the space with background colors it was necessary.

One issue I did encounter was that trying to assign one of the grid items to 3 consecutive vertical rows broke the grid. Originally I was going to have the main content occupy rows 3, 4, and 5, but I couldn’t get it to work with more than 2 rows. That was only when trying to use named anchors. It wasn’t an issue using a different method as we’ll see in example 2.

Variation of the css grid created using different grid positioning properties

CSS Grid Example 2

Example 2 is another common layout you might encounter on a web page. The css grid that’s in place is the same one I used above. Once again it’s 3 columns wide and 6 rows deep.

The html is the same as above, except for the removal of the #sidebar div. The css on the #grid div is also the same except for the removal on the named areas on the grid-template property.

[code type=css]
#grid {
display: grid;

grid-definition-columns: 1fr 1fr 1fr;
grid-definition-rows: 40px 150px 1fr 1fr 1fr 50px;
}
[/code]

The main difference between the two examples is in how I positioned the grid items inside the grid. Instead of using named areas, I experimented with some of the other grid properties.

[code type=css]
#navbar { grid-column-start: 1; grid-column-end: span 3; }
#header { grid-column-start: 1; grid-column-end: span 3; grid-row-start: 2; grid-row-end: 3}
#main { grid-column-start: 2; grid-column-end: 4; grid-row-start: 3; grid-row-end: 6; }
#aside-1 { grid-column: 1; grid-row: 3; }
#aside-2 { grid-column: 1; grid-row: 4; }
#aside-3 { grid-column: 1; grid-row: 5; }
#footer { grid-column-start: 1; grid-column-end: span 3; grid-row-start: 6; grid-row-end: 6 }
[/code]

You can see I used several different positioning properties here. The asides are the simplest so let’s start with them. Each gets a value for grid-column and grid-row that corresponds where each should be located in the grid. All are in the first column and they sit in rows 3, 4, and 5. The values set actually represent the grid line each grid item should display after. Each aside is located just after vertical grid-line 1 and after different horizontal grid lines.

Because the navbar displays in row 1, it wasn’t necessary to set the row. Here the div should start after grid-line 1 and span 3 columns. The header and footer divs are similar, but each also needed to have its row set.

The main content div was the most complicated (at least in comparison to the other grid items). For the columns it starts after the second grid-line and ends at the 4th grid-line. I could have set the end with a span like I did with the other divs, but I was experimenting after all.

Setting the rows of the main div is similar. Here it starts after grid-row-line 3 and ends at grid-row-line 6, just before the last row. Unlike with the named areas, there was no issue having the main content div span 3 rows.

Observations

One positive thing I noticed in playing around with css grids is how quick and easy it is to rearrange the grid items. The divs could quickly be mapped to different named areas or the different values for grid-column, grid-row, etc. could be easily changed. The best part is no change to the html is necessary.

Using css grids, your structure and presentation are truly separate. Each of the elements you want to add to a grid container can be located anywhere in the html and it could still show inside the grid you set up through css.

After experimenting with css grids for just a few days, I’m already excited for when we can use them in practice. I realize that won’t be any time soon, but still it’s worth getting excited about and thinking of the day we can.

If you haven’t yet, give css grids a try. Open Chrome Canary or IE10+ and copy my code above to get you started. Remember if you use IE, you need the -ms prefix and if you use Chrome Canary, you need to enable the experimental web platform features flag. Read my post from earlier in the week if you need to remember some of the properties and how they work.

On Monday I’ll continue with the look ahead at css that’s on its way and talk about css clipping and masking.