CSS Grid in 2026: A Practical Guide for Real Layouts

Use CSS Grid for two-dimensional layouts where rows and columns must line up, like page shells, dashboards, and pricing tables. Use Flexbox for one-direction flow where content sets the size, like nav bars and button rows. I use both in the same component: Grid outside, Flexbox inside.
Part of the complete web design guide.
On this page
- Grid vs. Flexbox: pick by axis, not by hype
- The page shell, still the best first use
- Subgrid is the feature that actually changed things
- Container queries pair with Grid, not against it
- Things that still bite people
- Where this shows up in client work
- Start with one component
- FAQ
- Is CSS Grid safe to use without a fallback in 2026?
- Should I use Grid instead of Flexbox for everything?
- Do container queries replace media queries?
Most sites I touch still lean on Flexbox for everything, then hit a wall the moment a real layout shows up: a dashboard, a pricing table, a card grid where the rows need to line up. CSS Grid solves those problems cleanly, and in 2026 it’s finally safe to use the good parts everywhere. Here’s how I actually use it, and where I still don’t.
Grid vs. Flexbox: pick by axis, not by hype
The rule I give people is simple. If you’re laying things out along one direction and the content should decide the size, use Flexbox. If you’re defining a two-dimensional structure (rows and columns at the same time), use Grid. A nav bar is Flexbox. A page shell with a sidebar and a main column is Grid. A row of cards that wraps is Flexbox. A row of cards where every card’s footer lines up across the row is Grid.
They’re not competitors. I use both in the same component constantly. Grid for the outer structure, Flexbox for the bits inside.
The page shell, still the best first use
This is the layout that made Grid click for me years ago, and it hasn’t changed. Named areas make the markup readable for whoever inherits it.
.layout {
display: grid;
grid-template-columns: 16rem 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
min-height: 100dvh;
gap: 1.5rem;
}
.layout > header { grid-area: header; }
.layout > aside { grid-area: sidebar; }
.layout > main { grid-area: main; }
.layout > footer { grid-area: footer; }
@media (max-width: 48rem) {
.layout {
grid-template-columns: 1fr;
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
}
}
Note 100dvh instead of 100vh. On mobile browsers the dynamic viewport unit accounts for the address bar sliding in and out, so you stop getting that annoying jump.
Subgrid is the feature that actually changed things
For years the complaint about Grid was that nested grids couldn’t share tracks with their parent. You’d build a card grid, then the card internals couldn’t align to the outer rows without hardcoding heights. Subgrid fixed that, and as of 2026 it’s supported across all current evergreen browsers, so I no longer treat it as a progressive enhancement.
.cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
gap: 1.5rem;
}
.card {
display: grid;
grid-row: span 3;
grid-template-rows: subgrid;
gap: 0.5rem;
}
.card h3 { margin: 0; }
.card .body { align-self: start; }
.card .cta { align-self: end; }
Now every card’s title, body, and call-to-action sit on the same horizontal lines across the whole row, no matter how much text each one has. Before subgrid you’d fake this with fixed heights or a JavaScript pass. Both were worse.
Container queries pair with Grid, not against it
Grid decides structure. Container queries decide how a component behaves based on the space it’s actually in, not the viewport. That combination is what makes a component genuinely reusable across a wide main column and a narrow sidebar.
.card-wrap {
container-type: inline-size;
}
.card {
display: grid;
gap: 1rem;
}
@container (min-width: 30rem) {
.card {
grid-template-columns: 8rem 1fr;
align-items: center;
}
}
The card lays out horizontally when it has room and stacks when it doesn’t, and it doesn’t care where on the page it lives. I’ve stopped writing “sidebar variant” and “full-width variant” classes because of this.
Things that still bite people
auto-fitvsauto-fill:auto-fitcollapses empty tracks so items stretch to fill the row.auto-fillkeeps the empty tracks, leaving gaps. For a card grid you almost always wantauto-fit.- Minimum content size. Grid items default to
min-width: auto, which means a long unbroken string or a wide<pre>block can blow out your column. Fix it withmin-width: 0on the item. - Don’t animate
grid-template-columnsdirectly. It’s not smoothly interpolable in most cases. Animate a transform or use a transition on the item instead. - Accessibility: Grid doesn’t change DOM order. If you reorder visually with
grid-area, keyboard tab order still follows the markup. Keep the source order sensible.
Where this shows up in client work
Most of what I build is custom sites and web apps for small businesses around here, and the layout problems are the same whether it’s a restaurant menu page or an internal dashboard. Grid handles the structure, Flexbox handles the rows, container queries handle reuse. That’s the whole mental model. If you’re weighing whether to rebuild an aging site on a modern layout system, that’s the kind of thing I work through as a Long Island web design project, and the answer is usually “yes, but not all at once.”
Start with one component
You don’t need to rewrite your CSS. Pick the ugliest layout on your site, the one held together with negative margins and a media query you’re scared to touch, and rebuild just that in Grid. Use named areas so the next person can read it. Add subgrid if you have nested rows that need to line up. Leave everything else alone until you have a reason.
FAQ
Is CSS Grid safe to use without a fallback in 2026?
Yes. Grid and subgrid are supported in all current evergreen browsers. The only reason to keep a fallback is if you specifically support very old enterprise browsers, which is rare now.
Should I use Grid instead of Flexbox for everything?
No. Use Grid for two-dimensional structure and Flexbox for one-dimensional rows or columns. Using Grid for a simple row of buttons just adds CSS for no benefit.
Do container queries replace media queries?
They replace them for component-level decisions. You still want media queries for page-level things like switching the whole shell from two columns to one. Use both.


