A lot of responsive design advice still floating around predates CSS features that make the old approach (media-query-driven breakpoints for everything) unnecessary for a growing share of layout problems.
clamp() — fluid values without media queries
h1 {
font-size: clamp(1.5rem, 4vw + 1rem, 3rem);
}clamp(min, preferred, max) gives you a value that scales smoothly with viewport width, but never shrinks below the minimum or grows past the maximum. This replaces what used to require multiple media query breakpoints just to step font sizes up at different widths — one line, continuously fluid, no jumps.
Container queries — the fix for component-based design
The historical limitation of media queries: they respond to the viewport's size, not the size of the component itself. A card component that needs to lay out differently depending on how much space its parent container gives it (not the whole page) couldn't respond to that with media queries alone — you'd need to know exactly which page layouts it would be dropped into.
.card-container {
container-type: inline-size;
}
@container (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 120px 1fr;
}
}Now the .card component switches to a side-by-side layout whenever its own container is at least 400px wide — regardless of whether that's a full-width page section or a narrow sidebar. This is what actually enables truly reusable, self-contained responsive components.
Intrinsic sizing keywords
.sidebar {
width: min(300px, 100%);
}
.gallery {
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}auto-fit with minmax() creates a grid that automatically fits as many 200px-minimum columns as will fit, wrapping to a new row as needed — a responsive grid with zero media queries and zero JavaScript, driven entirely by how much space is available.
Where media queries are still the right tool
Container queries and fluid sizing don't replace media queries entirely — they're still the right tool for layout decisions that genuinely depend on the viewport, not a component's local context: switching a whole page from a multi-column layout to a single column, hiding a desktop-only navigation element on small screens, or adjusting overall page padding.
@media (max-width: 640px) {
.page-layout {
grid-template-columns: 1fr;
}
}Testing responsively — beyond resizing the browser
Chrome DevTools' device toolbar (Cmd/Ctrl+Shift+M) simulates specific device viewports, but real device testing still catches things simulation doesn't: actual touch target sizing, real font rendering, and genuine performance on lower-powered hardware. For anything shipping broadly, test on at least one real phone, not just a resized desktop browser window.
The practical shift in mindset
The old approach: design for a few fixed breakpoints (mobile, tablet, desktop) and hope everything in between looks acceptable. The current approach, enabled by clamp(), container queries, and intrinsic sizing: design components that respond continuously to whatever space they're actually given, with media queries reserved specifically for page-level layout decisions. It's less "pick three screen sizes to design for" and more "design something that doesn't have a size it breaks at."