Holy Grail Layout
The most classic web layout pattern: a full-height page with a header, three-column content area (navigation, main content, aside), and a footer. Once notoriously complex — with CSS Grid it takes 15 lines. sdfsdfs
1. Basic Holy Grail
The core structure: header spans full width, three columns fill remaining height with 1fr, footer spans full width. The grid-template shorthand defines rows and areas together.
CSS
.page {
display: grid;
min-height: 100vh;
grid-template:
"header header header" auto
"nav main aside" 1fr
"footer footer footer" auto
/ 200px 1fr 180px;
gap: 0; /* or use gap for spacing */
}
.header { grid-area: header; }
.nav { grid-area: nav; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }2. Verbose Version (for Clarity)
The same layout written with separate properties. This is more readable when learning — once you understand it, use the shorthand.
CSS
.page {
display: grid;
min-height: 100vh;
grid-template-columns: 200px 1fr 180px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
}
/* Each child just assigns itself to an area */
.header { grid-area: header; }
.nav { grid-area: nav; }
.main { grid-area: main; }
.aside { grid-area: aside; }
.footer { grid-area: footer; }3. Responsive Holy Grail
On mobile, redefine the areas to stack everything vertically. The header stays, sidebar collapses below main, footer stays at the bottom.
CSS
.page {
display: grid;
grid-template-columns: 200px 1fr 180px;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
min-height: 100vh;
}
@media (max-width: 768px) {
.page {
grid-template-columns: 1fr;
grid-template-rows: auto;
grid-template-areas:
"header"
"main"
"nav"
"aside"
"footer";
}
}4. Variant: Sticky Header & Scrollable Main
A common app pattern where the header is sticky, the main area scrolls, and the footer sticks to the bottom. Uses height: 100vh on the grid container and overflow: auto on main.
CSS
.app {
display: grid;
height: 100vh; /* not min-height! */
grid-template-columns: 200px 1fr;
grid-template-rows: 60px 1fr 40px;
grid-template-areas:
"header header"
"nav main"
"footer footer";
}
.header {
grid-area: header;
position: sticky; top: 0; z-index: 10;
}
.main {
grid-area: main;
overflow-y: auto; /* scrollable! */
}