Designing Responsive Pages with CSS Grid's grid-template-areas
A practical look at using grid-template-areas to build clear, maintainable responsive layouts without nested flexbox or float hacks.
08 May 2026, 13:39 UTC

The problem: tangled markup for responsive layouts
Traditional approaches to page structure often rely on nested float or flexbox containers. As breakpoints multiply, the HTML order must be shuffled or duplicated to achieve the desired visual order, leading to fragile markup and CSS that is hard to read.
Why grid-template-areas helps
CSS Grid introduces a two-dimensional layout model. The grid-template-areas property lets you assign semantic names to rectangular cells, creating a visual map directly in the stylesheet. Because the map lives in CSS, you can rewrite it inside a media query without touching the DOM. This keeps HTML clean and makes the responsive intent obvious at a glance.
Key concepts
- Grid container – the element with
display: grid. - Named area – a string token (e.g.,
"header") that represents one or more contiguous cells. - Fractional unit (
fr) – distributes remaining space proportionally among tracks. - Gap – the
gapproperty (orrow-gap/column-gap) adds gutters without margin hacks.
Worked example: a classic three-column layout
The following snippet builds a page with a header, a left sidebar, main content, a right sidebar, and a footer. On screens narrower than 720 px the sidebars stack below the main area.
/* Base layout – wide screens */
.page {
display: grid;
grid-template-columns: 200px 1fr 200px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"sidebar-main content sidebar-right"
"footer footer footer";
gap: 1rem;
}
.header { grid-area: header; }
.sidebar-main { grid-area: sidebar-main; }
.content { grid-area: content; }
.sidebar-right { grid-area: sidebar-right; }
.footer { grid-area: footer; }
/* Responsive adjustment */
@media (max-width: 720px) {
.page {
grid-template-columns: 1fr;
grid-template-rows: auto auto auto auto auto;
grid-template-areas:
"header"
"content"
"sidebar-main"
"sidebar-right"
"footer";
}
}
In the wide view the three columns share space using a fixed-width sidebar (200 px) and a flexible middle (1fr). The gap property guarantees consistent gutters. When the viewport shrinks, the media query redefines the grid to a single column, stacking the named areas in a logical reading order. No HTML changes are required.
Trade-offs and limits
- Maintainability – Very large area maps (dozens of rows/columns) become difficult to visualise in source code. Consider splitting the layout into sub-grids or using line-based placement for complex sections.
- Implicit tracks – If a child is placed in an area not defined by
grid-template-areas, the browser creates implicit rows or columns, which can produce unexpected whitespace. Always audit with the browser's grid overlay (DevTools → Layout → Grid). - Legacy browsers – Internet Explorer 10/11 only support the old
-ms-gridsyntax and lackgrid-template-areas. If IE support is mandatory, provide a fallback using flexbox or a polyfill.
Actionable closing
- Add
display: gridto a container and sketch the desired areas on paper or in a comment block. - Write the
grid-template-areasstrings for the widest breakpoint first. - Insert a single media query that rewrites the area map for the next breakpoint.
- Open the page in Chrome, Firefox, or Safari, enable the grid overlay, and verify that each named area aligns with its element.
- Run a quick accessibility check (tab order, landmark roles) to ensure the visual reordering does not break reading flow.
By treating layout as a declarative map, grid-template-areas reduces the mental overhead of responsive design and keeps the stylesheet as the single source of truth for structure.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.