March 19, 2026
Why I still reach for plain CSS Grid
Utility classes are great for spacing and color. For the actual structure of a page, I still write the grid by hand.
I use Tailwind on most projects, including this one. It’s genuinely good at what it’s good at: spacing, color, typography scale, states — the high-frequency, low-risk decisions that don’t benefit from being bespoke. But for the actual skeleton of a page, I still reach for a hand-written CSS Grid.
Utility classes optimize for the wrong axis
grid-cols-12 gets you twelve equal columns. Most real layouts aren’t twelve equal columns — they’re a sidebar that wants exactly 280px, a content column that wants to grow, and a rail that wants to disappear below a breakpoint. You can express that in utility classes, but by the time you do, you’re writing more characters than the plain CSS would have taken, and the intent is harder to read back later.
Named lines read like documentation
.layout {
display: grid;
grid-template-columns: [sidebar-start] 280px [sidebar-end content-start] 1fr [content-end];
gap: 2rem;
}
Six months later, grid-column: content-start / content-end tells you what the element is for. col-start-4 col-end-9 tells you where a number happens to sit today, and nothing about why.
The actual rule I use
If a layout decision is about this specific page’s structure — how many regions there are, how they relate to each other, what happens when one collapses — it’s plain CSS Grid, named lines, in a scoped stylesheet. If it’s a spacing or color decision that repeats across dozens of components, it’s a utility class. The line isn’t about which tool is better. It’s about which decisions are worth naming.