🛠 Real-World Use
Named areas shine in layouts like:
Web page templates (header, sidebar, content, footer)
Dashboards
Responsive sections
They make the layout self-explanatory — no need to remember grid line numbers.
🧱 Simplified Layout Example
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>CSS Grid: Full Holy-Grail Layout</title>
<style>
.infographic-holygrail2 {
--ink: #1a1a1a;
--ink-soft: #5c5c5c;
--paper: #ffffff;
--paper-alt: #f0ece4;
--accent: #2563eb;
--accent-soft:#e3ebfd;
--line: #ddd6c9;
box-sizing: border-box;
margin: 0 auto;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
background: var(--paper);
color: var(--ink);
border-radius: 14px;
overflow: hidden;
}
.infographic-holygrail2[data-theme="dark"] {
--ink: #e8e6e1;
--ink-soft: #9a968c;
--paper: #121212;
--paper-alt: #1e1e26;
--accent: #5b8def;
--accent-soft:#202942;
--line: #2c313d;
}
.hg2-inner { padding: 0.5rem; }
.hg2-layout { display: flex; flex-direction: column; gap: 1.5rem; }
.hg2-code-wrap {
background: #0b0b0b;
border: 1px solid #2a2a2a;
border-radius: 10px;
overflow: hidden;
}
.hg2-filetabs {
display: flex;
background: #161616;
border-bottom: 1px solid #2a2a2a;
}
.hg2-filetab {
border: none;
background: transparent;
color: #8a8a8a;
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
font-size: 0.78rem;
font-weight: 700;
padding: 0.6rem 1rem;
cursor: pointer;
border-bottom: 2px solid transparent;
transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.hg2-filetab:hover { color: #e5e5e5; }
.hg2-filetab.hg2-tab-on {
color: #ffffff;
border-bottom-color: #5b8def;
background: #0b0b0b;
}
.hg2-code {
padding: 1rem 1.8rem 1rem 0.9rem;
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
font-size: 0.8rem;
line-height: 1.85;
overflow-x: auto;
}
.hg2-codepane { display: none; }
.hg2-codepane.hg2-pane-on { display: block; }
.hg2-line { display: block; white-space: pre; color: #8a8a8a; padding: 0.05rem 0.4rem; border-radius: 5px; }
.hg2-line.hg2-clickable { cursor: pointer; color: #e5e5e5; transition: background 0.15s ease, box-shadow 0.15s ease; }
.hg2-line.hg2-clickable:hover { background: #1c2333; }
.hg2-line.hg2-active { background: #1c2333; box-shadow: inset 3px 0 0 #5b8def; color: #ffffff; }
.hg2-tag { color: #60a5fa; font-weight: 700; }
.hg2-attr { color: #f2b96b; }
.hg2-str { color: #9ece6a; }
.hg2-sel { color: #f472b6; font-weight: 700; }
.hg2-prop { color: #c586c0; }
.hg2-val { color: #ce9178; }
.hg2-area-str { color: #9ece6a; font-weight: 700; }
.hg2-com { color: #6a6a6a; font-style: italic; }
.hg2-browser {
border: 1px solid var(--line);
border-radius: 10px;
overflow: hidden;
background: var(--paper);
}
.hg2-browser-bar {
background: var(--paper-alt);
padding: 0.5rem 0.7rem;
display: flex;
align-items: center;
gap: 0.5rem;
border-bottom: 1px solid var(--line);
}
.hg2-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--line); }
.hg2-tab {
background: var(--paper);
border: 1px solid var(--line);
border-bottom: none;
border-radius: 6px 6px 0 0;
font-size: 0.72rem;
color: var(--ink-soft);
padding: 0.25rem 0.6rem;
}
.hg2-urlrow {
background: var(--paper-alt);
padding: 0.35rem 0.7rem 0.6rem;
font-size: 0.72rem;
color: var(--ink-soft);
font-family: "SFMono-Regular", Consolas, monospace;
}
.hg2-screen {
background: #ffffff;
padding: 1rem;
}
.hg2-out-grid {
display: grid;
grid-template-columns: 60px 1fr 60px;
grid-template-rows: 44px 1fr 44px;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
gap: 8px;
height: 260px;
}
.hg2-out-item {
font-weight: bold;
text-align: left;
color: white;
display: flex;
align-items: center;
padding: 0 10px;
box-sizing: border-box;
font-size: 0.78rem;
transition: outline 0.2s ease, opacity 0.2s ease;
}
.hg2-out-header { grid-area: header; background: #4a90e2; justify-content: center; }
.hg2-out-nav { grid-area: nav; background: #f39c12; color: #1a1a1a; align-items: flex-start; padding-top: 10px; }
.hg2-out-main { grid-area: main; background: #ecf0f1; color: #1a1a1a; align-items: flex-start; padding-top: 10px; }
.hg2-out-aside { grid-area: aside; background: #e74c3c; align-items: flex-start; padding-top: 10px; }
.hg2-out-footer { grid-area: footer; background: #2c3e50; justify-content: center; }
.hg2-out-lit { outline: 3px solid var(--accent); outline-offset: 2px; }
.hg2-dim { opacity: 0.35; }
.hg2-note {
font-size: 0.82rem;
color: var(--ink-soft);
padding: 0 0.2rem;
}
.hg2-note strong { color: var(--ink); }
.hg2-note code {
font-family: "SFMono-Regular", Consolas, monospace;
background: var(--paper-alt);
padding: 0.05rem 0.3rem;
border-radius: 4px;
}
</style>
</head>
<body>
<div class="infographic-holygrail2" id="hg2-root">
<div class="hg2-inner">
<div class="hg2-layout">
<div class="hg2-code-wrap">
<div class="hg2-filetabs">
<button class="hg2-filetab hg2-tab-on" id="hg2-tab-css">style.css</button>
<button class="hg2-filetab" id="hg2-tab-html">index.html</button>
</div>
<div class="hg2-code">
<div class="hg2-codepane hg2-pane-on" id="hg2-pane-css">
<span class="hg2-line"><span class="hg2-sel">.grid</span> {</span>
<span class="hg2-line"> <span class="hg2-prop">display</span>: <span class="hg2-val">grid</span>;</span>
<span class="hg2-line"> <span class="hg2-prop">grid-template-columns</span>: <span class="hg2-val">1fr 3fr 1fr</span>;</span>
<span class="hg2-line"> <span class="hg2-prop">grid-template-rows</span>: <span class="hg2-val">auto 1fr auto</span>;</span>
<span class="hg2-line hg2-clickable" data-part="header"> <span class="hg2-prop">grid-template-areas</span>:</span>
<span class="hg2-line hg2-clickable" data-part="header"> <span class="hg2-area-str">"header header header"</span></span>
<span class="hg2-line hg2-clickable" data-part="grid-row2"> <span class="hg2-area-str">"nav main aside"</span></span>
<span class="hg2-line hg2-clickable" data-part="footer"> <span class="hg2-area-str">"footer footer footer"</span>;</span>
<span class="hg2-line"> <span class="hg2-prop">gap</span>: <span class="hg2-val">10px</span>;</span>
<span class="hg2-line">}</span>
<span class="hg2-line hg2-clickable" data-part="header"><span class="hg2-sel">header</span> { <span class="hg2-prop">grid-area</span>: <span class="hg2-val">header</span>; }</span>
<span class="hg2-line hg2-clickable" data-part="nav"><span class="hg2-sel">nav</span> { <span class="hg2-prop">grid-area</span>: <span class="hg2-val">nav</span>; }</span>
<span class="hg2-line hg2-clickable" data-part="main"><span class="hg2-sel">main</span> { <span class="hg2-prop">grid-area</span>: <span class="hg2-val">main</span>; <span class="hg2-com">/* overflow-y: auto */</span> }</span>
<span class="hg2-line hg2-clickable" data-part="aside"><span class="hg2-sel">aside</span> { <span class="hg2-prop">grid-area</span>: <span class="hg2-val">aside</span>; }</span>
<span class="hg2-line hg2-clickable" data-part="footer"><span class="hg2-sel">footer</span> { <span class="hg2-prop">grid-area</span>: <span class="hg2-val">footer</span>; }</span>
</div>
<div class="hg2-codepane" id="hg2-pane-html">
<span class="hg2-line"><<span class="hg2-tag">div</span> <span class="hg2-attr">class</span>=<span class="hg2-str">"grid"</span>></span>
<span class="hg2-line hg2-clickable" data-part="header"> <<span class="hg2-tag">header</span>>Header</<span class="hg2-tag">header</span>></span>
<span class="hg2-line hg2-clickable" data-part="nav"> <<span class="hg2-tag">nav</span>>Menu</<span class="hg2-tag">nav</span>></span>
<span class="hg2-line hg2-clickable" data-part="main"> <<span class="hg2-tag">main</span>>Main</<span class="hg2-tag">main</span>></span>
<span class="hg2-line hg2-clickable" data-part="aside"> <<span class="hg2-tag">aside</span>>Ads</<span class="hg2-tag">aside</span>></span>
<span class="hg2-line hg2-clickable" data-part="footer"> <<span class="hg2-tag">footer</span>>Footer</<span class="hg2-tag">footer</span>></span>
<span class="hg2-line"></<span class="hg2-tag">div</span>></span>
</div>
</div>
</div>
<div class="hg2-browser">
<div class="hg2-browser-bar">
<span class="hg2-dot"></span><span class="hg2-dot"></span><span class="hg2-dot"></span>
<div class="hg2-tab">🌐 Holy Grail Layout</div>
</div>
<div class="hg2-urlrow">127.0.0.1:5500/index.html</div>
<div class="hg2-screen">
<div class="hg2-out-grid" id="hg2-out-grid">
<div class="hg2-out-item hg2-out-header hg2-out-lit" id="hg2-out-header">Header</div>
<div class="hg2-out-item hg2-out-nav" id="hg2-out-nav">Menu</div>
<div class="hg2-out-item hg2-out-main" id="hg2-out-main">Main</div>
<div class="hg2-out-item hg2-out-aside" id="hg2-out-aside">Ads</div>
<div class="hg2-out-item hg2-out-footer" id="hg2-out-footer">Footer</div>
</div>
</div>
</div>
<div class="hg2-note" id="hg2-note">
Every row string now has <strong>3</strong> words, matching the 3 explicit columns — <code>header</code> and <code>footer</code> span all three by repeating their name, while row 2 gives each column a distinct name.
</div>
</div>
</div>
</div>
<script>
(function () {
const wrapper = document.getElementById('hg2-root');
const bodyAttr = document.body.getAttribute('data-darkmode');
let dark;
if (bodyAttr === 'true') {
dark = true;
} else if (bodyAttr === 'false') {
dark = false;
} else {
const match = document.cookie.match(/(?:^|;\s*)darkMode=([^;]+)/);
dark = match ? match[1] === 'true' : false;
}
if (dark) wrapper.setAttribute('data-theme', 'dark');
})();
(function () {
const tabCss = document.getElementById('hg2-tab-css');
const tabHtml = document.getElementById('hg2-tab-html');
const paneCss = document.getElementById('hg2-pane-css');
const paneHtml = document.getElementById('hg2-pane-html');
tabCss.addEventListener('click', () => {
tabCss.classList.add('hg2-tab-on');
tabHtml.classList.remove('hg2-tab-on');
paneCss.classList.add('hg2-pane-on');
paneHtml.classList.remove('hg2-pane-on');
});
tabHtml.addEventListener('click', () => {
tabHtml.classList.add('hg2-tab-on');
tabCss.classList.remove('hg2-tab-on');
paneHtml.classList.add('hg2-pane-on');
paneCss.classList.remove('hg2-pane-on');
});
const notes = {
header: 'Every row string now has <strong>3</strong> words, matching the 3 explicit columns — <code>header header header</code> spans all three by repeating the name.',
'grid-row2': '<code>"nav main aside"</code> gives each of the 3 columns its own distinct name in row 2 — nothing left unclaimed.',
nav: '<strong>nav</strong> claims the narrow left column (<code>1fr</code>) in the middle row.',
main: '<strong>main</strong> takes the wide center column (<code>3fr</code>) — the bulk of the page.',
aside: '<strong>aside</strong> claims the narrow right column (<code>1fr</code>) — this is the column that was empty before.',
footer: '<code>"footer footer footer"</code> spans all 3 columns, mirroring the header.'
};
const outMap = {
header: ['hg2-out-header'],
'grid-row2': ['hg2-out-nav', 'hg2-out-main', 'hg2-out-aside'],
nav: ['hg2-out-nav'],
main: ['hg2-out-main'],
aside: ['hg2-out-aside'],
footer: ['hg2-out-footer']
};
const note = document.getElementById('hg2-note');
document.querySelectorAll('.hg2-line.hg2-clickable').forEach(line => {
line.addEventListener('click', () => {
const part = line.getAttribute('data-part');
document.querySelectorAll('.hg2-line').forEach(l => {
l.classList.toggle('hg2-active', l.getAttribute('data-part') === part);
});
document.querySelectorAll('.hg2-out-item').forEach(el => {
el.classList.remove('hg2-out-lit');
el.classList.add('hg2-dim');
});
(outMap[part] || []).forEach(id => {
const el = document.getElementById(id);
el.classList.add('hg2-out-lit');
el.classList.remove('hg2-dim');
});
if (notes[part]) note.innerHTML = notes[part];
});
});
})();
</script>
</body>
</html>* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: sans-serif;
height: 100vh; /* Ensures body fills viewport */
}
.grid {
display: grid;
height: 100vh; /* Full page height */
grid-template-columns: 1fr 3fr 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header header"
"nav main aside"
"footer footer footer";
gap: 10px;
padding: 20px;
}
header {
grid-area: header;
background-color: #4a90e2;
color: white;
padding: 20px;
text-align: center;
}
nav {
grid-area: nav;
background-color: #f39c12;
padding: 20px;
}
main {
grid-area: main;
background-color: #ecf0f1;
padding: 20px;
overflow-y: auto; /* Scrolls if content grows */
}
aside {
grid-area: aside;
background-color: #e74c3c;
color: white;
padding: 20px;
}
footer {
grid-area: footer;
background-color: #2c3e50;
color: white;
text-align: center;
padding: 20px;
}💡 Why Use Area Names?
Without Names | With Names |
|---|---|
grid-column: 1 / 3; | grid-area: header; |
Hard to visualize layout | Easy to see the structure |
Tedious to update | Simple to modify later |
Combine with media queries to rearrange layout responsively just by changing the
grid-template-areas.