Responsive: units, queries, variables
rem vs px, mobile-first, container queries, clamp() and custom properties.
Updated
What responsive means
Responsive = the same HTML looks good on a 360px phone and on a 2560px monitor. You don't build two sites — you build a layout that adapts.
Three tools: flexible units, media / container queries and fluid layouts (flex, grid).
Units — types and when to use them
| Unit | Relative to | When |
|---|---|---|
px |
nothing (fixed) | borders, shadows, small details |
rem |
the root font-size (html, usually 16px) |
font-size, spacing — respects the user's zoom setting |
em |
the element's font-size | padding that grows with the button's text |
% |
the parent | relative widths |
vw / vh |
the window | full-screen sections |
dvh |
the real window on mobile (without the browser bar) | min-height: 100dvh |
ch |
the width of the "0" character | max-width: 65ch — readable lines |
Media queries
.grid { grid-template-columns: 1fr; }
@media (min-width: 48rem) {
.grid { grid-template-columns: repeat(2, 1fr); }
}Mobile-first: you write the style for small screens, then add on with min-width. The code is simpler and mobile (most of the traffic) loads less CSS.
Other useful media queries: (prefers-color-scheme: dark), (prefers-reduced-motion: reduce), (hover: hover).
Container queries
Media queries look at the screen; container queries look at the parent. A card reused in a narrow sidebar and on a wide page adapts on its own:
.card-wrapper { container-type: inline-size; }
@container (min-width: 30rem) {
.card { display: flex; }
}Fluid typography with clamp()
h1 { font-size: clamp(1.75rem, 1rem + 3vw, 3rem); }clamp(minimum, preferred, maximum) — grows smoothly with the screen, but stays within the limits. No need for dozens of breakpoints.
CSS variables (custom properties)
:root { --space: 1rem; --brand: #1f5fbf; }
.btn { padding: var(--space); background: var(--brand); }
@media (min-width: 64rem) {
:root { --space: 1.5rem; } /* all spacing grows from a single line */
}Unlike Sass variables, CSS variables live in the browser: they're inherited and can change at runtime and inside media queries. Themes in Tailwind are built on them.
Responsive images
img { max-width: 100%; height: auto; }next/image automatically generates several sizes (srcset) and picks the one that fits the screen.
Summary
remfor text and spacing,pxfor details,dvhon mobile.- Mobile-first with
min-width; container queries for components. clamp()for fluid typography, CSS variables for tokens.