Holy grail layout (CSS Grid)
The classic header, sidebar, content, aside and footer layout in a few lines using grid-template-areas.
Bar color#1f2330
Accent#7c5cff
Gap8px
<div class="layout"><header class="layout__h">Header</header><nav class="layout__nav">Nav</nav><main class="layout__main">Main content</main><aside class="layout__aside">Aside</aside><footer class="layout__f">Footer</footer></div> :root {
--bar: #1f2330;
--accent: #7c5cff;
--gap: 8px;
}
.layout {
display: grid;
gap: var(--gap);
min-height: 260px;
grid-template:
"header header header" auto
"nav main aside" 1fr
"footer footer footer" auto
/ 100px 1fr 100px;
color: #fff;
}
.layout__h { grid-area: header; }
.layout__nav { grid-area: nav; }
.layout__main { grid-area: main; }
.layout__aside{ grid-area: aside; }
.layout__f { grid-area: footer; }
.layout > * {
padding: 12px;
border-radius: 8px;
background: var(--bar);
}
.layout__h, .layout__f { border-block: 2px solid var(--accent); } How it works
grid-template draws the whole page as a picture: each quoted row names the
cells, and the sizes after the / set the column track widths.
- The named areas (
header,nav,main,aside,footer) are assigned to elements withgrid-area, so the markup order doesn’t matter. - The middle row is
1fr— it grows to fill the height; the bars areauto. - Columns are
100px 1fr 100px: fixed sidebars hugging a flexible center.
To go single-column on mobile, just redefine the areas in a media query:
@media (max-width: 600px) {
.layout {
grid-template:
"header" auto "nav" auto "main" 1fr
"aside" auto "footer" auto / 1fr;
}
}
For a card grid that reflows on its own, see the responsive grid with no media queries.