1 · unit resolution: px vs em vs rem vs vw
This page pins html { font-size:16px }, so 1 rem == 16px no matter the
viewport. em is the trickster: on font-size it means "my parent's
font-size", so it compounds down a nested tree. rem ("root em") always
jumps straight back to <html>. Every number below is measured live via
getComputedStyle.
| unit | relative to | 2×unit → |
|---|---|---|
| px | nothing (absolute) | — |
| em | parent font-size (here 20px) | — |
| rem | root <html> font-size | — |
| vw | 1% of viewport width | — (varies!) |
2 · media query vs container query — viewport vs component
A media query (@media) reacts to the viewport — global, so the same
component can't look right in a wide sidebar and a narrow main column. A container
query (@container) reacts to the component's own box: drag the slider to
shrink the host and the card reflows without touching the window.
Component card
This card flips horizontal when its container ≥ 400px — regardless of the viewport.
3 · fluid type with clamp()
Skip the breakpoint ladder: clamp(MIN, PREFERRED, MAX) scales a value smoothly between two
absolutes. Here the heading is clamp(1rem, 6vw, 2.5rem) — never below 16px, never above 40px,
and fluid in between. Resize the window and watch the measured px glide.
Fluid heading — clamp(1rem, 6vw, 2.5rem)
—
—
—