Modern CSS Layout: Stop Reaching for a Framework First
Grid, Flexbox, custom properties and container queries cover the vast majority of what a CSS framework does — without 200KB and a class name for every pixel.
CSS frameworks solved a real problem in 2013. Browsers have since shipped almost everything they were working around. It is worth knowing what you no longer need.
Grid for Two Dimensions, Flexbox for One
That is the whole decision. A page layout with rows and columns is Grid. A row of buttons that need to space out is Flexbox.
.projects-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1.5rem;
}
That one rule is a responsive card grid with no media queries at all. It adapts to the container, not to guessed device widths.
Custom Properties Are a Design System
:root {
--yellow: #FFD700;
--surface: rgba(255,255,255,.03);
--space: 1.5rem;
}
Define your palette and spacing scale once. Theme switching then becomes redefining a handful of variables rather than rewriting every rule.
clamp() Kills Most Typography Media Queries
h1 { font-size: clamp(1.8rem, 5vw, 3.5rem); }
A minimum, a preferred scaling value, and a maximum. One line replaces three breakpoints.
Container Queries Fix the Real Problem
A card does not care how wide the viewport is. It cares how wide its container is. That is what container queries finally give us.
.card-wrap { container-type: inline-size; }
@container (min-width: 420px) {
.card { grid-template-columns: 120px 1fr; }
}
:has() Is a Parent Selector
.form-group:has(input:invalid) { border-color: crimson; }
Something we asked for for fifteen years, now supported everywhere that matters.
When a Framework Still Makes Sense
Large teams needing enforced consistency, or a prototype you need tomorrow. For a bespoke design on a site you control, hand-written CSS is smaller, faster and easier to change.