Media Queries Modern Approach
Modern @media — mobile-first ranges, range syntax, preference queries, and when container queries replace viewport breakpoints.
- css
- media-queries
- responsive
Media queries still drive viewport-level layout and user preference hooks. The modern approach is mobile-first min-width bands, fewer magic breakpoints, range syntax where supported, and a clear split between page shell (@media) and component (@container) concerns.
Docs: MDN @media, Using media queries, Media Queries Level 4.
Mobile-first baseline
.nav__links {
display: none;
}
@media (min-width: 48rem) {
.nav__links {
display: flex;
gap: 1rem;
}
}
Start from the small layout as default CSS, then add complexity at larger sizes. Prefer rem-based breakpoints so they track user font size better than raw px (teams still use px; be consistent).
Range syntax
/* Legacy pair */
@media (min-width: 48rem) and (max-width: 79.99rem) { }
/* Modern range */
@media (width >= 48rem) and (width < 80rem) { }
@media (48rem <= width < 80rem) {
.layout {
grid-template-columns: 12rem 1fr;
}
}
Support is strong in current engines; keep legacy form if your baseline requires it.
Preference queries (not optional)
@media (prefers-color-scheme: dark) {
:root {
--surface: #0f1419;
--text: #e7ecf1;
}
}
@media (prefers-reduced-motion: reduce) {
.hero {
animation: none;
}
}
@media (prefers-contrast: more) {
:root {
--border: #000;
}
}
These are user settings, not device widths. Don’t bury them under “nice to have.”
Pointer and hover capability
@media (hover: hover) and (pointer: fine) {
.card:hover {
transform: translateY(-2px);
}
}
@media (pointer: coarse) {
.button {
min-height: 44px;
}
}
Avoid relying on hover-only affordances for essential actions.
@media print {
.app-nav,
.toast {
display: none !important;
}
a[href]::after {
content: " (" attr(href) ")";
}
}
See also dedicated print stylesheet patterns.
Media vs container
/* Shell: how many columns in the page grid */
@media (min-width: 64rem) {
.page {
grid-template-columns: 16rem 1fr;
}
}
/* Component: card density based on slot */
@container (min-width: 24rem) {
.card {
grid-template-columns: 8rem 1fr;
}
}
If a widget appears in sidebar and main, container queries prevent “viewport is wide but my column isn’t” bugs.
Interview out-loud
“I write mobile-first CSS and layer min-width queries for larger shells. I use preference queries for color scheme and reduced motion, and pointer queries for hover vs coarse input. Component-level responsiveness belongs in container queries. Breakpoints should map to design needs, not every device model.”
Footguns
- Desktop-first max-width soup that’s hard to extend.
- Too many breakpoints for minor font tweaks — use
clamp. - Hover styles as the only way to show controls on touch.
- Testing only browser resize, not real device toolbars /
dvh. - Hard-coding
pxbreakpoints that ignore user zoom preferences (know the tradeoff).
Breakpoint tokens
:root {
--bp-md: 48rem;
--bp-lg: 64rem;
}
/* Cannot use var() in @media in classic CSS — document tokens and duplicate values, or use a preprocessor/lightningcss plugin */
@media (min-width: 48rem) {
.nav__toggle { display: none; }
.nav__links { display: flex; }
}
Name breakpoints by layout intent (nav-inline, two-col) in comments even if values are numeric. Avoid device names (iphone, ipad) — they rot.
Testing matrix
Resize alone misses: zoom 200%, large system font, landscape phone, split-screen tablets, and print. Pair media queries with container queries so components survive unusual shells (settings pages with narrow main columns on wide monitors).
Related
Further reading
Related guides
- Container QueriesStyle components from their container size with @container — name containment, units like cqi, and when media queries still win.
- Accent Color and Form ControlsUse accent-color to theme native checkboxes, radios, ranges, and progress — what it paints, what it skips, and when to custom-style instead.
- Auto-fit vs Auto-fillauto-fit collapses empty tracks; auto-fill keeps them. Use both with minmax for responsive card grids without media-query soup.
- BEM Naming MethodologyBlock, Element, Modifier naming for CSS — how it limits specificity wars, what to name, and when utility or CSS modules beat strict BEM.
- blend-mode Basicsmix-blend-mode vs background-blend-mode — how pixels combine, isolation, and the stacking/readability traps in product UI.