One thing we’ve mentioned, but have yet to cover properly in this series is grid areas. So far our grid items have each been contained within a single grid cell, but we can achieve more useful layouts by breaking beyond those boundaries. Let’s take a look!
Defining Grid Areas
Here’s the grid we’ve been working on: nine grid items automatically placed within three equal columns, three equal rows, split by gutters of 20px.
Currently our items only have color styles, but let’s return to what we learned in the first tutorial and add some grid-column
and grid-row
rules, this time with something extra:
.item-1 { background: #b03532; grid-column: 1 / 3; grid-row: 1; }
In this shorthand grid-column
statement we’re effectively using grid-column-start
and grid-column-end
, telling the item to start at grid line 1 and end at grid line 3.
Here’s what that gives us; the first item now spreads across two cells, pushing the other items right and down according to Grid’s auto-placement algorithm.
The same can be done with rows, which would give us a much larger area in the top left of our grid.
.item-1 { background: #b03532; grid-column: 1 / 3; grid-row: 1 / 3; }
Spanning Cells
Using what is perhaps an easier syntax we can switch grid-column-end
for the span
keyword. With span
we aren’t tied to specifying where the area ends, instead defining how many tracks the item should spread across:
.item-1 { background: #b03532; grid-column: 1 / span 2; grid-row: 1 / span 2; }
This gives us the same end result, but if we were to change where we want the item to start we would no longer be obliged to change the end.
In the following demo you can see we’ve emptied the layout by removing four of the items. We’ve declared positioning on two of our items: the first spans two columns and two rows, whilst the fourth starts on column 3, row 2, and spans downward across two tracks:
The remaining items fill the available space automatically. This highlights perfectly how a grid layout doesn’t have to reflect the source order of the elements.
Note: there are many situations where the source order absolutely should reflect the presentation–don’t forget about accessibility.
Named Areas
Using the numbering methods we’ve described so far works just fine, but Grid Template Areas can make defining layouts even more intuitive.
Specifically, they allow us to name areas on the grid. With those areas named, we can reference them (instead of line numbers) to position our items. Let’s stick to our current demo for the moment and use it to make ourselves a rough page layout comprising:
- header
- main content
- sidebar
- footer
We define these areas on our grid container, almost as though we’re drawing them out:
.grid-1 { /* ..existing styles */ grid-template-areas: "header header header" "main main sidebar" "footer footer footer"; }
Positioning the Items
Now we turn our attention to the items, ditching the grid-column
and grid-row
rules in favor of grid-area
:
.item-1 { background: #b03532; grid-area: header; } .item-2 { background: #33a8a5; grid-area: main; } .item-3 { background: #30997a; grid-area: sidebar; } .item-4 { background: #6a478f; grid-area: footer; }
Our first item is slotted into the header, spanning across all three header columns. Our second item is assigned the main content area, the third becomes our sidebar, and the fourth our footer. And these needn’t follow the source order either–.item-4
could just as easily be positioned in the header area.
As you can see, this makes laying out a page much easier. In fact, while we’re in the mood for visually representing our grids, why not go even further and use emojis?!
Nesting Grid Areas
A given web page will contain all kinds of nested components, so let’s see how that works with Grid.
When we declare a grid container display: grid;
only its direct descendants become grid items. Content we add to those child elements will be completely unaffected by Grid unless we specifically say otherwise.
In our example, we’re going to add .item-5
, .item-6
, and .item-7
back into the markup, nesting them in .item-2
.
<section class="grid-1"> <div class="item-1">1</div> <div class="item-2"> <div class="item-5">5</div> <div class="item-6">6</div> <div class="item-7">7</div> </div> <div class="item-3">3</div> <div class="item-4">4</div> </section>
So now we need to declare our .item-2
also a grid container, setting up its grid with two columns and two rows.
display: grid; grid-template-columns: 1fr 30%; grid-template-rows: auto auto; grid-gap: 20px; grid-template-areas: "header header" "article sidebar";
We can use the names “header”, “article”, and “sidebar” again here; there’s no confusion, because everything stays in context. These grid areas only apply to the grid within .item-2
.
Conclusion
To sum up what we’ve been talking about:
-
grid-column
offers us a shorthand way of defining where an item starts and ends.
- We can also use the
span
keyword to make our rules more flexible. -
grid-template-areas
give us the power to name our grid areas (even using emojis if the mood takes us).
- We can also nest grids by declaring grid items as
display: grid;
and following the same process.
Once again we’ve learned some useful aspects of the CSS Grid Layout spec, and we’re getting closer and closer to real world use cases! In the next tutorial we’ll look at some more complex layouts and see how responsive design fits into the equation.
Useful Resources
- Have I mentioned this already? Follow @rachelandrew
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Update me weeklyEnvato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post