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

grid-template-areasgrid-templategrid-areamin-height: 100vh

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; }
MyApp
HomeAboutBlogContact
Menu
Dashboard
Posts
Users
Settings
Main Content
Revenue
Views
Orders
Rating
Sidebar
Recent
Popular
Tags
Archive
© 2026 MyApp. All rights reserved.
PrivacyTermsContact
The secret is grid-template shorthand: each quoted string is a row's named areas, followed by its height. After the slash, list the column widths.

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; }
Header
Nav
Main Content Area
Aside
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";
  }
}
Desktop
Header
Nav
Main
Aside
Footer
Mobile (stacked)
Header
Main Content
Nav (below main on mobile)
Aside
Footer
On mobile, main comes before nav in the visual order — even though nav might be first in the DOM. Grid areas let you reorder visually without touching HTML.

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! */
}
App
sticky header
Home
Posts
Users
Tags
Settings
Scrollable Content
sticky footer
Key difference: use height: 100vh (not min-height) so the grid is exactly the viewport height. Then overflow: auto on the main area creates a scrollable content region.