CSS Grid Layout: getting to grips with the Chrome implementation

I’ve been following the CSS3 Grid Layout specification since the early days, writing about the IE10 implementation in my book CSS3 Layout Modules and for 24 Ways. When I last wrote an update here everything was theoretical, as there was no browser implementation at the time. Now, with support for the latest version of the spec in Chrome, I thought it a good time to revisit how my favourite CSS module is getting along.

This material was created for my talk at Responsive Day Out, here are the resources and slides for that presentation.

How to play with Grid

To play with Grid in a browser you need to enable Experimental Web Platform Features in Chrome. You will then be able to use Grid, you don’t need to prefix any properties or values. A couple of these examples only work right now in Chrome Canary.

Declaring a Grid

To declare a Grid on an element, you need to use a new value for the display property, display: grid. Any elements inside that parent will now stack up visually.

.wrapper {
  display: grid;
}

The first step is to declare what your Grid looks like. This can be anything from a simple three column layout to a complex 16 column grid structure. The following will create a simple grid of three main columns and two gutter columns. A bit like an old school liquid layout.

.wrapper {
  display: grid;
  grid-template-columns: 200px 40px auto 40px 200px;
  grid-template-rows: auto 1fr;
}

If you look at your page now, you’ll find everything stacked up in the first 200 pixel wide column. This is because without any Grid Positioning applied to the child elements of .wrapper they default to the top left cell of the grid.

We can then start positioning our items onto our Grid.

I am using line-based positioning here. A crucial thing to bear in mind when working with Grid is that you need to target lines, not columns. So when positioning the main content I use:

.content {
  grid-column-start: 3;
  grid-column-end: 4;
  grid-row-start: 2;
  grid-row-end: 3;
}

This could also be written in a shorthand format using the grid-row and grid-column properties:

.content {
  grid-column: 3 / 4;
  grid-row: 2 / 3;
}

You can see this example over on CodePen – remember you will need to use Chrome to see the Grid in action.

Simple Layout with Grid – line-based placement

I have also created an example using Media Queries to redefine the layout at different breakpoints.

Responsive Layout with Grid – line-based placement

Grid Template Areas

If battling with all of these lines gets confusing, there is a simpler way to set up and then target parts of your Grid. When you define your Grid you can also provide names for the main content areas, using the grid-template-areas property.

.mainnav {
  grid-area: nav;
}
.subhead {
  grid-area: subhead;
}
.quote {
  grid-area: quote;
}
.content {
  grid-area: content;
}
.feature-image {
  grid-area: feature;
}

Placing an item into an area is then as simple as assigning the name of the area it should be placed into.

@media only screen and (min-width: 980px) {
  .wrapper {
    display: grid;
	 grid-template-columns: 200px 40px auto 40px 200px;
	 grid-template-rows: auto auto auto;
	 grid-template-areas: 
       ". . subhead . ."
       "nav . feature . quote"
       "nav . content . quote";
  }	
}	

If you take a look at the code for this example, I am creating a simple responsive design by first setting up my named areas outside of the media queries. Inside my Media Queries I then redefine the grid, setting the location of each element.

This example highlights the thing about Grid that really got me excited when I first looked at the spec. Grid allows us to properly separate source order from layout. The big feature image and the quote in this example are found in the source below the content. However I can pop them anywhere on the Grid at different layout widths. This means that we can start to work out what is best to sit where at different screen sizes and for different devices and display the content visually in that order – while keeping it in a sensible structure in the source.

A 16 column layout example and named Grid Lines

You can also assign names to lines. This becomes useful if you want to create a formal grid to position elements onto. Here I am declaring a Grid with 16 columns – the line before the column is named “col”, the line before the gutter is named “gutter” (remember: name lines not columns).

.wrapper {	 
  display:grid;
  grid-template-columns: (gutter) 1fr repeat(16, (col) 4.25fr (gutter) 1fr );
  grid-template-rows: repeat(9, (row) auto (gutter) 20px );
}

I can then place items onto this grid using the span keyword to say how many col or gutter lines I should span. To create a full width header:

.header { 
  grid-column: col / span gutter 16; 
  grid-row: row / span 1;
}

To position the content area:

.content { 
  grid-column: col 5 / span gutter 8; 
  grid-row: row 2 / span 1;
}

To see and play with a couple of example take a look on CodePen at an example of positioning blocks onto that 16 column grid, and an example of positioning more realistic content onto the grid. As of today this example only works in Chrome Canary.

If you are interested you can see a similar example using the initial IE10 syntax. I wrote about that early implementation in my piece for 24 Ways. Defining this kind of 16 column grid at that point required doing calculations to work out how to place the items and I find it interesting to see how the spec has evolved into something that really is quite simple to use – once you get your head round the basic concepts.

If learning about Grid, and other newer CSS Layout Modules, is of interest to you take a look at my upcoming second edition of CSS Layout Modules – a little book of practical examples.

Comments

Šime Vidas: 11 Jul 2014 at 01:26:33

Btw Firefox Nightly also has an experimental Grid implementation (behind a “grid” flag) but it doesn’t seem to support your demos yet (for some reason)

Odin Hørthe Omdal: 11 Jul 2014 at 09:30:58

Very nice article :) Once this is turned on by default I’ll start using it for internal systems (with very graceful degradation of course!).

All the code also runs in Opera 24 by the way (after switching on the Experimental web platform features flag). Not really that surprising as we’re Chromium based, but all this canary-talk seems a bit strange. It does seem to work in current Opera 24 developer (which is Chromium 37, also in dev stream).

Odin Hørthe Omdal: 11 Jul 2014 at 09:33:21

Oups, I did not look at the date since I saw this on Twitter (thinking everything is written same day). Of course this was all different on June 24th! But 37 is now in dev stream :P

Pete: 24 Jul 2014 at 08:31:29

Thanks for writing this post Rachel. Very thorough as usual and helps make sense of the new spec.

ken: 17 Aug 2014 at 09:46:29

Is safari support this ?

Sergio: 01 Sep 2014 at 15:15:27

Nice post Rachel!

BTW, you can also follow the implementation of grid layout in Blink and WebKit in some Igalia’s developer blogs like
https://blogs.igalia.com/svillar, https://blogs.igalia.com/mrego or https://blogs.igalia.com/jfernandez. Hope it helps!

Leave a reply