Many websites are a variation of this type of layout, with content, sidebars, a header and a footer. In a responsive design, you may want to display the layout as a single column, adding a sidebar at a certain breakpoint and then bring in a three-column layout for wider screens.
We're going to create this layout using the named template areas that we learned about in the guide Grid template areas.
The markup is a container with elements inside for a header, footer, main content, navigation, sidebar, and a block to place advertising.
<div class="wrapper">
<header class="main-head">The header</header>
<nav class="main-nav">
<ul>
<li><a href="">Nav 1</a></li>
<li><a href="">Nav 2</a></li>
<li><a href="">Nav 3</a></li>
</ul>
</nav>
<article class="content">
<h1>Main article area</h1>
<p>
In this layout, we display the areas in source order for any screen less
that 500 pixels wide. We go to a two column layout, and then to a three
column layout by redefining the grid, and the placement of items on the
grid.
</p>
</article>
<aside class="side">Sidebar</aside>
<div class="ad">Advertising</div>
<footer class="main-footer">The footer</footer>
</div>
As we are using grid-template-areas
to create the layout. Outside of any media queries we need to name the areas. We name areas using the grid-area
property.
.main-head {
grid-area: header;
}
.content {
grid-area: content;
}
.main-nav {
grid-area: nav;
}
.side {
grid-area: sidebar;
}
.ad {
grid-area: ad;
}
.main-footer {
grid-area: footer;
}
This will not create any layout, however the items now have names we can use to do so. Staying outside of any media queries we're now going to set up the layout for the mobile width. Here we're keeping everything in source order, trying to avoid any disconnect between the source and display as described in the guide Grid layout and accessibility. We've not defined any column or row tracks but this layout dictates a single column, and rows will be created as needed for each of the items in the implicit grid.
.wrapper {
display: grid;
gap: 20px;
grid-template-areas:
"header"
"nav"
"content"
"sidebar"
"ad"
"footer";
}
With our mobile layout in place, we can now proceed to add a media query to adapt this layout for bigger screens with enough real estate to display two columns.
@media (min-width: 500px) {
.wrapper {
grid-template-columns: 1fr 3fr;
grid-template-areas:
"header header"
"nav nav"
"sidebar content"
"ad footer";
}
nav ul {
display: flex;
justify-content: space-between;
}
}
You can see the layout taking shape in the value of grid-template-areas
. The header
spans over two column tracks, as does the nav
. In the third row track we have the sidebar
alongside the content
. In the fourth row track I have chosen to place my ad
content – so it appears under the sidebar, then the footer
next to it under the content. We're using a flexbox on the navigation to display it in a row spaced out.
We can now add a final breakpoint to move to a three-column layout.
@media (min-width: 700px) {
.wrapper {
grid-template-columns: 1fr 4fr 1fr;
grid-template-areas:
"header header header"
"nav content sidebar"
"nav content ad"
"footer footer footer";
}
nav ul {
flex-direction: column;
}
}
The three-column layout has two 1fr
unit side columns and a middle column that has 4fr
as the track size. This means that the available space in the container is split into 6 and assigned in proportion to our three tracks – one part each to the side columns and 4 parts to the center.
In this layout we're displaying the nav
in the left column, alongside the content
. In the right column we have the sidebar
and underneath it the advertisements (ad
). The footer
now spans right across the bottom of the layout. I then use a flexbox to display the navigation as a column.
This is a simple example but demonstrates how we can use a grid layout to rearrange our layout for different breakpoints. In particular we're changing the location of that ad
block, as appropriate in my different column setups. I find this named areas method very helpful at a prototyping stage, it is easy to play around with the location of elements. You could always begin to use grid in this way for prototyping, even if you can't rely on it fully in production due to the browsers that visit your site.