30 CSS Grid Layouts07 / 30
Holy Grail
The canonical three-row, three-column holy grail — presented as the teaching version: every region labelled with its grid-area name, a visible track diagram, and the exact 2000s-era problems (equal-height columns, footer at the bottom, source-order independence) annotated as solved. The reference students bookmark.
Published Updated
The code
<section class="cgl-07" aria-label="Holy grail layout demo">
<div class="cgl-07__shell">
<header class="cgl-07__masthead"><h3>The Holy Grail</h3><p>solved in one declaration since 2017</p></header>
<nav class="cgl-07__menu" aria-label="Sections"><span class="cgl-07__tag">menu · 160px</span><a href="#0">Front page</a><a href="#0">Archive</a><a href="#0">About</a></nav>
<main class="cgl-07__content"><span class="cgl-07__tag">content · minmax(0,1fr)</span><p>Equal-height columns? Automatic — grid items stretch to their row. Fluid center? The 1fr track. Footer at the bottom on short pages? The 1fr <em>row</em>. Three famous problems, zero hacks.</p></main>
<aside class="cgl-07__extras"><span class="cgl-07__tag">extras · 160px</span><p>Source order stays semantic; the grid places regions visually.</p></aside>
<footer class="cgl-07__colophon"><span class="cgl-07__tag">colophon</span><p>grid-template: areas / rows / columns — one shorthand, whole page.</p></footer>
</div>
</section><section class="cgl-07" aria-label="Holy grail layout demo">
<div class="cgl-07__shell">
<header class="cgl-07__masthead"><h3>The Holy Grail</h3><p>solved in one declaration since 2017</p></header>
<nav class="cgl-07__menu" aria-label="Sections"><span class="cgl-07__tag">menu · 160px</span><a href="#0">Front page</a><a href="#0">Archive</a><a href="#0">About</a></nav>
<main class="cgl-07__content"><span class="cgl-07__tag">content · minmax(0,1fr)</span><p>Equal-height columns? Automatic — grid items stretch to their row. Fluid center? The 1fr track. Footer at the bottom on short pages? The 1fr <em>row</em>. Three famous problems, zero hacks.</p></main>
<aside class="cgl-07__extras"><span class="cgl-07__tag">extras · 160px</span><p>Source order stays semantic; the grid places regions visually.</p></aside>
<footer class="cgl-07__colophon"><span class="cgl-07__tag">colophon</span><p>grid-template: areas / rows / columns — one shorthand, whole page.</p></footer>
</div>
</section>.cgl-07,
.cgl-07 *,
.cgl-07 *::before,
.cgl-07 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cgl-07 {
width: 100%;
min-height: 100vh;
--cream: oklch(0.96 0.02 90);
--ink: oklch(0.28 0.04 50);
--red: oklch(0.55 0.19 30);
font-family: Georgia,'Times New Roman',serif;
background: var(--cream);
color: var(--ink);
padding: 1.4rem;
}
.cgl-07 .cgl-07__shell {
display: grid;
grid-template: "masthead masthead masthead" auto "menu content extras" 1fr "colophon colophon colophon" auto / 160px minmax(0,1fr) 160px;
gap: 2px;
min-block-size: 360px;
background: var(--ink);
border: 2px solid var(--ink);
border-radius: 6px;
overflow: hidden;
}
.cgl-07 .cgl-07__shell>* {
background: var(--cream);
padding: 1rem;
}
.cgl-07 .cgl-07__masthead {
grid-area: masthead;
display: flex;
align-items: baseline;
gap: 1rem;
border-block-end: none;
}
.cgl-07 .cgl-07__masthead h3 {
font-size: 1.4rem;
font-variant: small-caps;
letter-spacing: .04em;
}
.cgl-07 .cgl-07__masthead p {
font-size: .78rem;
font-style: italic;
color: color-mix(in oklab,var(--ink) 65%,var(--cream));
}
.cgl-07 .cgl-07__menu {
grid-area: menu;
display: flex;
flex-direction: column;
gap: 6px;
}
.cgl-07 .cgl-07__menu a {
font-size: .85rem;
color: var(--ink);
text-decoration: none;
border-block-end: 1px dotted color-mix(in oklab,var(--ink) 40%,var(--cream));
padding-block: .35rem;
overflow-wrap: break-word;
}
.cgl-07 .cgl-07__menu a:hover {
color: var(--red);
}
.cgl-07 .cgl-07__menu a:focus-visible {
outline: 2px solid var(--red);
outline-offset: 2px;
}
.cgl-07 .cgl-07__content {
grid-area: content;
}
.cgl-07 .cgl-07__extras {
grid-area: extras;
}
.cgl-07 .cgl-07__colophon {
grid-area: colophon;
display: flex;
align-items: baseline;
gap: 1rem;
background: oklch(0.92 0.025 85);
}
.cgl-07 .cgl-07__tag {
display: block;
font-family: ui-monospace,Menlo,monospace;
font-size: .62rem;
color: var(--red);
background: color-mix(in oklab,var(--red) 10%,var(--cream));
border: 1px solid color-mix(in oklab,var(--red) 35%,var(--cream));
border-radius: 4px;
padding: .2rem .45rem;
inline-size: fit-content;
margin-block-end: .6rem;
}
.cgl-07 p {
font-size: .85rem;
line-height: 1.6;
}
@media (max-width: 600px) {
.cgl-07 .cgl-07__shell {
grid-template: "masthead" auto "menu" auto "content" 1fr "extras" auto "colophon" auto / 1fr;
}
}.cgl-07,
.cgl-07 *,
.cgl-07 *::before,
.cgl-07 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cgl-07 {
width: 100%;
min-height: 100vh;
--cream: oklch(0.96 0.02 90);
--ink: oklch(0.28 0.04 50);
--red: oklch(0.55 0.19 30);
font-family: Georgia,'Times New Roman',serif;
background: var(--cream);
color: var(--ink);
padding: 1.4rem;
}
.cgl-07 .cgl-07__shell {
display: grid;
grid-template: "masthead masthead masthead" auto "menu content extras" 1fr "colophon colophon colophon" auto / 160px minmax(0,1fr) 160px;
gap: 2px;
min-block-size: 360px;
background: var(--ink);
border: 2px solid var(--ink);
border-radius: 6px;
overflow: hidden;
}
.cgl-07 .cgl-07__shell>* {
background: var(--cream);
padding: 1rem;
}
.cgl-07 .cgl-07__masthead {
grid-area: masthead;
display: flex;
align-items: baseline;
gap: 1rem;
border-block-end: none;
}
.cgl-07 .cgl-07__masthead h3 {
font-size: 1.4rem;
font-variant: small-caps;
letter-spacing: .04em;
}
.cgl-07 .cgl-07__masthead p {
font-size: .78rem;
font-style: italic;
color: color-mix(in oklab,var(--ink) 65%,var(--cream));
}
.cgl-07 .cgl-07__menu {
grid-area: menu;
display: flex;
flex-direction: column;
gap: 6px;
}
.cgl-07 .cgl-07__menu a {
font-size: .85rem;
color: var(--ink);
text-decoration: none;
border-block-end: 1px dotted color-mix(in oklab,var(--ink) 40%,var(--cream));
padding-block: .35rem;
overflow-wrap: break-word;
}
.cgl-07 .cgl-07__menu a:hover {
color: var(--red);
}
.cgl-07 .cgl-07__menu a:focus-visible {
outline: 2px solid var(--red);
outline-offset: 2px;
}
.cgl-07 .cgl-07__content {
grid-area: content;
}
.cgl-07 .cgl-07__extras {
grid-area: extras;
}
.cgl-07 .cgl-07__colophon {
grid-area: colophon;
display: flex;
align-items: baseline;
gap: 1rem;
background: oklch(0.92 0.025 85);
}
.cgl-07 .cgl-07__tag {
display: block;
font-family: ui-monospace,Menlo,monospace;
font-size: .62rem;
color: var(--red);
background: color-mix(in oklab,var(--red) 10%,var(--cream));
border: 1px solid color-mix(in oklab,var(--red) 35%,var(--cream));
border-radius: 4px;
padding: .2rem .45rem;
inline-size: fit-content;
margin-block-end: .6rem;
}
.cgl-07 p {
font-size: .85rem;
line-height: 1.6;
}
@media (max-width: 600px) {
.cgl-07 .cgl-07__shell {
grid-template: "masthead" auto "menu" auto "content" 1fr "extras" auto "colophon" auto / 1fr;
}
}/* No JavaScript — the grid-template shorthand sets areas, rows and columns in a single declaration. */
/* No JavaScript — the grid-template shorthand sets areas, rows and columns in a single declaration. */Here's a working CSS Grid Layout from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Holy Grail
Source: https://codefronts.com/layouts/css-grid-layouts/holy-grail/
The canonical three-row, three-column holy grail — presented as the teaching version: every region labelled with its grid-area name, a visible track diagram, and the exact 2000s-era problems (equal-height columns, footer at the bottom, source-order independence) annotated as solved. The reference students bookmark.
## HTML
```html
<section class="cgl-07" aria-label="Holy grail layout demo">
<div class="cgl-07__shell">
<header class="cgl-07__masthead"><h3>The Holy Grail</h3><p>solved in one declaration since 2017</p></header>
<nav class="cgl-07__menu" aria-label="Sections"><span class="cgl-07__tag">menu · 160px</span><a href="#0">Front page</a><a href="#0">Archive</a><a href="#0">About</a></nav>
<main class="cgl-07__content"><span class="cgl-07__tag">content · minmax(0,1fr)</span><p>Equal-height columns? Automatic — grid items stretch to their row. Fluid center? The 1fr track. Footer at the bottom on short pages? The 1fr <em>row</em>. Three famous problems, zero hacks.</p></main>
<aside class="cgl-07__extras"><span class="cgl-07__tag">extras · 160px</span><p>Source order stays semantic; the grid places regions visually.</p></aside>
<footer class="cgl-07__colophon"><span class="cgl-07__tag">colophon</span><p>grid-template: areas / rows / columns — one shorthand, whole page.</p></footer>
</div>
</section>
```
## CSS
```css
.cgl-07,
.cgl-07 *,
.cgl-07 *::before,
.cgl-07 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cgl-07 {
width: 100%;
min-height: 100vh;
--cream: oklch(0.96 0.02 90);
--ink: oklch(0.28 0.04 50);
--red: oklch(0.55 0.19 30);
font-family: Georgia,'Times New Roman',serif;
background: var(--cream);
color: var(--ink);
padding: 1.4rem;
}
.cgl-07 .cgl-07__shell {
display: grid;
grid-template: "masthead masthead masthead" auto "menu content extras" 1fr "colophon colophon colophon" auto / 160px minmax(0,1fr) 160px;
gap: 2px;
min-block-size: 360px;
background: var(--ink);
border: 2px solid var(--ink);
border-radius: 6px;
overflow: hidden;
}
.cgl-07 .cgl-07__shell>* {
background: var(--cream);
padding: 1rem;
}
.cgl-07 .cgl-07__masthead {
grid-area: masthead;
display: flex;
align-items: baseline;
gap: 1rem;
border-block-end: none;
}
.cgl-07 .cgl-07__masthead h3 {
font-size: 1.4rem;
font-variant: small-caps;
letter-spacing: .04em;
}
.cgl-07 .cgl-07__masthead p {
font-size: .78rem;
font-style: italic;
color: color-mix(in oklab,var(--ink) 65%,var(--cream));
}
.cgl-07 .cgl-07__menu {
grid-area: menu;
display: flex;
flex-direction: column;
gap: 6px;
}
.cgl-07 .cgl-07__menu a {
font-size: .85rem;
color: var(--ink);
text-decoration: none;
border-block-end: 1px dotted color-mix(in oklab,var(--ink) 40%,var(--cream));
padding-block: .35rem;
overflow-wrap: break-word;
}
.cgl-07 .cgl-07__menu a:hover {
color: var(--red);
}
.cgl-07 .cgl-07__menu a:focus-visible {
outline: 2px solid var(--red);
outline-offset: 2px;
}
.cgl-07 .cgl-07__content {
grid-area: content;
}
.cgl-07 .cgl-07__extras {
grid-area: extras;
}
.cgl-07 .cgl-07__colophon {
grid-area: colophon;
display: flex;
align-items: baseline;
gap: 1rem;
background: oklch(0.92 0.025 85);
}
.cgl-07 .cgl-07__tag {
display: block;
font-family: ui-monospace,Menlo,monospace;
font-size: .62rem;
color: var(--red);
background: color-mix(in oklab,var(--red) 10%,var(--cream));
border: 1px solid color-mix(in oklab,var(--red) 35%,var(--cream));
border-radius: 4px;
padding: .2rem .45rem;
inline-size: fit-content;
margin-block-end: .6rem;
}
.cgl-07 p {
font-size: .85rem;
line-height: 1.6;
}
@media (max-width: 600px) {
.cgl-07 .cgl-07__shell {
grid-template: "masthead" auto "menu" auto "content" 1fr "extras" auto "colophon" auto / 1fr;
}
}
```
## JavaScript
```js
/* No JavaScript — the grid-template shorthand sets areas, rows and columns in a single declaration. */
```Here's a working CSS Grid Layout from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Holy Grail
Source: https://codefronts.com/layouts/css-grid-layouts/holy-grail/
The canonical three-row, three-column holy grail — presented as the teaching version: every region labelled with its grid-area name, a visible track diagram, and the exact 2000s-era problems (equal-height columns, footer at the bottom, source-order independence) annotated as solved. The reference students bookmark.
## HTML
```html
<section class="cgl-07" aria-label="Holy grail layout demo">
<div class="cgl-07__shell">
<header class="cgl-07__masthead"><h3>The Holy Grail</h3><p>solved in one declaration since 2017</p></header>
<nav class="cgl-07__menu" aria-label="Sections"><span class="cgl-07__tag">menu · 160px</span><a href="#0">Front page</a><a href="#0">Archive</a><a href="#0">About</a></nav>
<main class="cgl-07__content"><span class="cgl-07__tag">content · minmax(0,1fr)</span><p>Equal-height columns? Automatic — grid items stretch to their row. Fluid center? The 1fr track. Footer at the bottom on short pages? The 1fr <em>row</em>. Three famous problems, zero hacks.</p></main>
<aside class="cgl-07__extras"><span class="cgl-07__tag">extras · 160px</span><p>Source order stays semantic; the grid places regions visually.</p></aside>
<footer class="cgl-07__colophon"><span class="cgl-07__tag">colophon</span><p>grid-template: areas / rows / columns — one shorthand, whole page.</p></footer>
</div>
</section>
```
## CSS
```css
.cgl-07,
.cgl-07 *,
.cgl-07 *::before,
.cgl-07 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cgl-07 {
width: 100%;
min-height: 100vh;
--cream: oklch(0.96 0.02 90);
--ink: oklch(0.28 0.04 50);
--red: oklch(0.55 0.19 30);
font-family: Georgia,'Times New Roman',serif;
background: var(--cream);
color: var(--ink);
padding: 1.4rem;
}
.cgl-07 .cgl-07__shell {
display: grid;
grid-template: "masthead masthead masthead" auto "menu content extras" 1fr "colophon colophon colophon" auto / 160px minmax(0,1fr) 160px;
gap: 2px;
min-block-size: 360px;
background: var(--ink);
border: 2px solid var(--ink);
border-radius: 6px;
overflow: hidden;
}
.cgl-07 .cgl-07__shell>* {
background: var(--cream);
padding: 1rem;
}
.cgl-07 .cgl-07__masthead {
grid-area: masthead;
display: flex;
align-items: baseline;
gap: 1rem;
border-block-end: none;
}
.cgl-07 .cgl-07__masthead h3 {
font-size: 1.4rem;
font-variant: small-caps;
letter-spacing: .04em;
}
.cgl-07 .cgl-07__masthead p {
font-size: .78rem;
font-style: italic;
color: color-mix(in oklab,var(--ink) 65%,var(--cream));
}
.cgl-07 .cgl-07__menu {
grid-area: menu;
display: flex;
flex-direction: column;
gap: 6px;
}
.cgl-07 .cgl-07__menu a {
font-size: .85rem;
color: var(--ink);
text-decoration: none;
border-block-end: 1px dotted color-mix(in oklab,var(--ink) 40%,var(--cream));
padding-block: .35rem;
overflow-wrap: break-word;
}
.cgl-07 .cgl-07__menu a:hover {
color: var(--red);
}
.cgl-07 .cgl-07__menu a:focus-visible {
outline: 2px solid var(--red);
outline-offset: 2px;
}
.cgl-07 .cgl-07__content {
grid-area: content;
}
.cgl-07 .cgl-07__extras {
grid-area: extras;
}
.cgl-07 .cgl-07__colophon {
grid-area: colophon;
display: flex;
align-items: baseline;
gap: 1rem;
background: oklch(0.92 0.025 85);
}
.cgl-07 .cgl-07__tag {
display: block;
font-family: ui-monospace,Menlo,monospace;
font-size: .62rem;
color: var(--red);
background: color-mix(in oklab,var(--red) 10%,var(--cream));
border: 1px solid color-mix(in oklab,var(--red) 35%,var(--cream));
border-radius: 4px;
padding: .2rem .45rem;
inline-size: fit-content;
margin-block-end: .6rem;
}
.cgl-07 p {
font-size: .85rem;
line-height: 1.6;
}
@media (max-width: 600px) {
.cgl-07 .cgl-07__shell {
grid-template: "masthead" auto "menu" auto "content" 1fr "extras" auto "colophon" auto / 1fr;
}
}
```
## JavaScript
```js
/* No JavaScript — the grid-template shorthand sets areas, rows and columns in a single declaration. */
```How this works
One declaration block replaces a decade of float clearing: grid-template: "masthead masthead masthead" auto "menu content extras" 1fr "colophon colophon colophon" auto / 160px minmax(0,1fr) 160px — the shorthand that sets areas, rows and columns together. Equal-height columns are automatic because grid items stretch to their row by default; the footer stays put because the middle row is 1fr.
The retro-print styling is the point of difference: the demo renders its own track diagram in a corner using nested mini-grids, so learners see the geometry and the result side by side. All three classic requirements — fluid center, fixed rails, footer pinning — are called out with in-layout annotations.
Make it yours
- Make the rails fluid with
minmax(140px, 18%)instead of fixed 160px. - Convert to app-frame: set the shell to
block-size: 100dvhand addoverflow-y: autoon the content region only. - Restack for mobile with the included single media query.
- Rename areas to your team's vocabulary — the names are yours, only the rectangle rule is the spec's.
Gotchas — read before shipping
- The grid-template shorthand resets grid-auto-* properties — declare it before any auto-flow tweaks.
- Fixed-width rails need content discipline; a 200px word will overflow a 160px track (use overflow-wrap: break-word on nav labels).
- Don't confuse this with demo 04: same areas concept, but this one teaches the shorthand + fixed rails; 04 teaches fluid minmax rails.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.2+ | 113+ | 111+ |
Floor set by oklch(), color-mix() as this demo is written. The core technique itself goes back further — Chrome 57+.
Pure original-spec grid — runs in everything since 2017. This is the safest layout on the page.