Home / Snippets / Layout & Grid /
Holy grail layout
The classic five-region page layout (header, nav sidebar, main content, aside sidebar, footer) using CSS Grid.
Quick implementation
.holy-grail {
display: grid;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
grid-template-columns: 12rem 1fr 12rem;
grid-template-rows: auto 1fr auto;
min-height: 100dvh;
gap: 0;
}
.holy-grail > header { grid-area: header; }
.holy-grail > nav { grid-area: nav; }
.holy-grail > main { grid-area: main; }
.holy-grail > aside { grid-area: aside; }
.holy-grail > footer { grid-area: footer; }
/* Stack on narrow screens */
@media (max-width: 48rem) {
.holy-grail {
grid-template-areas:
"header"
"nav"
"main"
"aside"
"footer";
grid-template-columns: 1fr;
}
}
Prompt this to your LLM
Paste this into ChatGPT, Claude, or any code-generating model to scaffold the pattern instantly.
Build a "holy grail" page layout using CSS Grid. The
container should have grid-template-areas with three rows:
"header header header", "nav main aside", and
"footer footer footer". Set grid-template-columns to
12rem 1fr 12rem and grid-template-rows to auto 1fr auto.
Give it min-height: 100dvh. Assign grid-area to each
direct child: header, nav, main, aside, footer. Add a
media query at max-width: 48rem that collapses everything
into a single column by redefining grid-template-areas
and setting grid-template-columns: 1fr.
Why this matters
The holy grail layout was notoriously difficult before CSS Grid, requiring floats, clearfixes, and equal-height column hacks. With grid-template-areas, the entire layout is expressed in a readable ASCII-art grid map. Changing the layout for different screen sizes is as simple as rewriting the area strings in a media query. This is the foundational layout for dashboards, documentation sites, and content-heavy applications.
The logic
The grid-template-areas property defines named regions in a visual grid map. Each row is a quoted string, and repeated names span multiple columns. The header and footer each span all three columns. The middle row has nav, main, and aside side by side. grid-template-columns: 12rem 1fr 12rem gives fixed-width sidebars and a fluid center. grid-template-rows: auto 1fr auto makes the header and footer size to their content while the middle row takes all remaining vertical space, achieving a full-height layout with min-height: 100dvh.
Accessibility & performance
Use proper semantic elements: <header>, <nav>, <main>, <aside>, and <footer>. These give screen readers a navigable landmark structure automatically. Grid reordering (changing area assignments) changes only the visual order, not the DOM order, so keep the source order logical for keyboard and screen-reader users. The grid layout is computed once by the browser on render and does not trigger expensive reflows during scroll. Using 100dvh instead of 100vh avoids the mobile address-bar height issue.