CSS Grid is the layout system best suited for two-dimensional WordPress theme layouts — page templates with header, sidebar, main content, and footer regions — while Flexbox excels at one-dimensional component-level layouts within those regions. A CSS Grid layout for a WordPress page template defines named grid areas with grid-template-areas that match the semantic HTML structure: header, nav, main, aside, and footer are placed into named cells, and the layout responds to viewport width by redefining the grid-template-areas string and grid-template-columns inside media queries. The fr unit distributes available space proportionally — grid-template-columns: 1fr 300px gives the main column all remaining space after a fixed 300px sidebar, which is more robust than percentage-based columns that require manual calculation. The minmax() function combined with auto-fill or auto-fit creates fully responsive grid galleries without media queries: grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)) creates as many 280px+ columns as fit in the container, wrapping automatically. Subgrid (CSS Grid Level 2, supported in all modern browsers since 2023) allows a child grid to inherit track definitions from its parent, which solves the long-standing problem of aligning text and images across cards in a grid row — set grid-row: span 4; display: grid; grid-template-rows: subgrid on each card and all cards in a row align their title, image, excerpt, and button to the same row tracks. Named grid lines (defined as [sidebar-start] in the grid-template-columns value) make placement intent explicit and allow component styles to reference named lines rather than numeric indices, surviving column order changes. The gap property (formerly grid-gap) sets consistent gutters between rows and columns without collapsing margin issues. The design tokens post shows how spacing tokens feed directly into gap and padding values across the grid layout.
Problem: A WordPress theme page template uses nested floats and absolute positioning to achieve a three-column layout with a sticky sidebar — the layout breaks on tablet viewports and requires 200+ lines of fragile CSS with magic-number pixel values to hold together.
Solution: Replace the float-based layout with a grid-template-areas page grid that stacks to a single column on mobile, switches to a two-column layout with sidebar on tablet, and expands to a three-region layout on desktop — all in under 40 lines of CSS.
/* ── Page layout grid ──────────────────────────────────────────────── */
.page-layout {
display: grid;
gap: var(--spacing-section) var(--spacing-component);
/* Mobile: single column stack */
grid-template-columns: 1fr;
grid-template-areas:
"header"
"nav"
"main"
"sidebar"
"footer";
}
@media (min-width: 768px) {
.page-layout {
grid-template-columns: 1fr 280px;
grid-template-areas:
"header header"
"nav nav"
"main sidebar"
"footer footer";
}
}
@media (min-width: 1200px) {
.page-layout {
grid-template-columns: 240px 1fr 280px;
grid-template-areas:
"header header header"
"nav nav nav"
"toc main sidebar"
"footer footer footer";
}
}
/* Place children into named areas */
.site-header { grid-area: header; }
.site-nav { grid-area: nav; }
.entry-content{ grid-area: main; }
.widget-area { grid-area: sidebar; }
.site-footer { grid-area: footer; }
.toc-panel { grid-area: toc; display: none; }
@media (min-width: 1200px) { .toc-panel { display: block; } }
/* ── Auto-fill post card grid (no media queries needed) ───────────── */
.post-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: var(--spacing-component);
}
/* ── Subgrid: align card internals across a row ────────────────────── */
.post-card {
grid-row: span 4; /* occupies 4 row tracks of the parent */
display: grid;
grid-template-rows: subgrid; /* inherit parent row tracks */
gap: 0;
}
/* Result: thumbnail / title / excerpt / button align across all cards in a row */
NOTE: Subgrid requires a parent grid to define the row tracks that children inherit — it does not create its own tracks. The parent .post-grid must set explicit row tracks with grid-auto-rows or grid-template-rows for subgrid alignment to work. Check caniuse.com/css-subgrid before using subgrid in production — as of mid-2023 it is supported in Chrome 117+, Firefox 71+, and Safari 16+ but not in older Android WebView versions.