CSS Grid Layout: Named Grid Lines and areas

Updated 10 May 2013, to add some corrections, clarifications and new information. Thanks to Tab Atkins Jr. for this detailed response on www-style

I really like Grid, as I explained to the Front Trends audience last week, my presentation The New CSS Layout is partly so I have an excuse to tell people about Grid. I also get quite excited about Regions and Exclusions but I feel Grid needs some love from the design and development community.

Feedback is being actively requested for this module, however it is pretty tricky to give feedback on a module that doesn’t really have any implementation. Therefore I’m reading the spec so you don’t have to and will post my thoughts and experiments as I make them. As I mentioned in my last article, some of this might change, some of it I may have misinterpreted. If you know better than I do please leave a comment and I’ll update the article.

I explained in my previous post how we place items on the grid using the grid placement properties and numerical values, I also cover this in my presentation. However specifying things by number has a couple of problems as several people that I discussed this with at Front Trends noted.

Firstly changes to the grid, for example adding a column, mean that every item will need to have it’s position updated.

Secondly, placing items by number means you constantly have to hold in your head a model of the grid to be able to place elements onto it. If you are placing elements programmatically then the numeric values make more sense than if you are building a layout by hand.

To attempt to solve these problems the Working Draft contains a proposal to assign names to grid lines and also areas of the grid, so that’s the bit of the spec I have been reading over the last few days.

Named grid lines

When you define your grid, you specify the columns that make up the grid.

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

When you place items on the grid, you specify the grid lines that surround that content area.

.content {  
  grid-start: 3;  
  grid-end: 4;  
  grid-before: 2;  
  grid-after: 3; 
}

If you want to name your grid lines, the proposal is that you will do it like this. Note that the name is for the line, the actual column width or height comes afterwards. You can have multiple names for the same line just by putting them one after the other, each wrapped in quotes, before the column or row size definition – I have done this for the column named as both “sidebar and “ads”.

.wrapper {  
  display: grid;  
  grid-definition-columns: "nav" 200px 
                           "gutter"  20px 
                           "main" auto 
                           "gutter" 20px 
                           "sidebar" "ads" 200px;  
  grid-definition-rows: "header" auto "content" 1fr; "content-end"  
}

You can then place items using the named line, rather than the number.

.content {  
  grid-start: "main';  
  grid-end: span 1;  
  grid-before: "content";  
  grid-after: span 1; 
}

This solves the problem of columns being added to the grid, making all the grid placement values incorrect. I think it will also make more sense for responsive design, you can redefine the grid using media queries, but content is always placed after the content row line for example no matter what they actual row grid line value.

In the above example I have two lines named “gutter”, this is valid, but how does the browser know which “gutter” line I mean?

When positioning items you can also use the span keyword. I found the spec pretty confusing here and my original article had a couple of errors, one I think caused by an earlier reading of the spec. I have updated this section as of 10th May 2013 to match the clarifications in the email linked at the start of this post

If you take this rule:

.nav
  grid-start: "nav";
  grid-end: "gutter";
}

The content area would begin at the first line – named nav – and end at the first gutter line as you might expect, however if you wanted the content to sit in the main content area of the page and end at the next gutter you need to use the span keyword. This shows that you don’t want the first gutter but that you want to start counting gutter lines after the line named main.

.nav
  grid-start: "main";
  grid-end: span "gutter";
}

This hacking around the lack of proper gutters looks to be a temporary thing. There is discussion on www-style regarding using column-gap much in the same way as it is used in multi-column layout. I think this would solve one of the current big issues with grid.

Grid template – for named grid areas

We can also name areas of the grid. We do this with the grid-template property on the element that has been set to display: grid. We create this template with named areas as a value of grid-template.

.wrapper {  
  display: grid;  
  grid-definition-columns: 200px 20px auto 20px 200px;  
  grid-definition-rows: auto 1fr; 
  grid-template: "header header header header header"
                       "nav . content . sidebar" 
}

If you want an area to span the entire grid – such as my header – then you should place it into each column of the template.

Once we have defined our grid and set up a template. We position items into these areas using the grid-area property.

.content {
  grid-area: content;
}

Again, this helps to solve the issue of the grid becoming redefined, and makes changing placement more straightforward in a responsive design context.

Why would you use one method over the other? From my basic experiments I think that the line based placement will be more useful for complex layouts, and for replicating existing grid systems such as the 12 and 16 column grids commonly used. I’ve attempted to create such a grid, although without any browser to test this in I can’t be sure as to the accuracy of this example. What the named grid lines give us over the old version of the spec that is implemented in IE10 is the ability to place items on the grid without needing to do any kind of calculation across rows and columns to account for gutters.

Compare the named grid lines version of the flexible grid with my original from my 24 Ways article. In the 24 Ways example I had to use a preprocessor to do the calculation, you could of course still use a preprocessor to make generating this syntax easier and there is also a shorthand syntax, I just feel that while I am still figuring it out it is easier to stick with the longhand to see what is going on!

If you have a fairly simple layout then the template based method may be the most straightforward, combined with Flexbox for smaller UI elements you could avoid the complexity of named grid lines and just target simple areas.

The working Group have asked for feedback, with the example above and the more complex one I posted on CodePen I just tried to figure out how I would implement typical layouts using this. I think that is a pretty good place to start. Could you create the layouts you want to create using Grid? If not, why not? Can you think of better naming for the Grid Placement Properties? This is the point at which it is possible to influence how a specification develops, once it gets to Candidate Recommendation Level major changes are unlikely to be made, so it is in all of our interests to think about this stuff and post our thoughts.

Leave a reply