CSS Clamp Table
| Piece | What it does | Field note |
|---|---|---|
clamp(min, preferred, max) | Fluid with a floor/ceiling | min/max are walls, preferred is the slider between |
fluid type recipe | clamp(1rem, 2.5vw, 1.5rem) | The headline fluid-type one-liner - no media queries |
min() / max() siblings | Two-argument versions | max(2rem, 5vw) = floor only; min = ceiling only |
vw units inside | The fluid driver | The preferred slot carries the viewport-proportional term |
ch for measures | Readable line caps | max-width: 70ch beats px - scales with the font |
rem not px in bounds | Respect user settings | px walls ignore user font prefs - rem walls honor them |
vs media queries | Continuous vs stepped | clamp flows continuously; breakpoints jump - fluid wins for sizes |
touch targets 44px | The interactive floor | clamp for widths; buttons still need real size floors |
clamp(MIN, PREFERRED, MAX) is fluid sizing without media queries: the middle term (usually viewport-driven like 2.5vw) slides continuously between hard walls - the fluid-type one-liner is clamp(1rem, 2.5vw, 1.5rem), a headline that scales with the screen but never leaves sane bounds.
Bottom line: min() and max() are the two-argument siblings (one wall each), ch units make readable line measures scale with the font (max-width: 70ch beats any pixel value), and bounds in REM honor the user's font-size preference where px walls silently ignore it.
The honest part: clamping is continuous responsiveness - it beats stepped breakpoints for SIZES because there are no jump points. But continuous sizing only answers 'how big'; layout changes (columns appearing, stacking to rows) still want real media or container queries.
How to use
- Fluid type in one line: h1 { font-size: clamp(1.8rem, 4vw, 3rem); } - scales from phone to desktop with no breakpoint, floored and capped.
- Readable measures in ch: p { max-width: 65ch; } - the line-length cap that scales with the font size, unlike any pixel value.
- Bounds in rem: clamp(1rem, 2.5vw, 1.5rem) - px walls silently ignore the user's browser font setting; rem walls respect it.
Frequently asked questions
How does clamp actually compute its value?
Three arguments, one rule: the result is the PREFERRED value, clamped between MIN and MAX. If preferred falls inside the range, you get preferred (typically viewport-proportional, so it tracks the screen); if it exceeds max, you get max; below min, you get min. The mental model is a slider with walls: 2.5vw is the slider's motion, 1rem and 1.5rem are the walls. This makes every clamp self-documenting - read the walls to know the extremes, read the middle to know how it moves - and self-responsive: no media query needed because the preferred term is already screen-relative.
Why use ch and rem inside clamp-based sizing instead of px?
Units carry intent. ch (the width of the '0' glyph) makes a line-measure cap SCALE WITH THE FONT: max-width: 65ch is always about 65 characters whether the user's base font is 14px or 24px - a px cap breaks one of those cases. rem makes bounds respect the USER'S root font-size preference: walls in px silently ignore a user who raised their default font size, shrinking their relative limits to nothing. The accessibility rule: dimensions that should track typography use typography-relative units (ch, rem, em); dimensions that are genuinely device-fixed (a 1px border) use px. Most sizing mistakes are unit mistakes.
When are clamp and fluid sizing better than media queries - and when not?
For SIZES, fluid wins: a font that scales continuously never hits a jump point where it is briefly wrong, and one declaration replaces four breakpoints of font-size overrides. For LAYOUT, breakpoints still rule: 'the sidebar becomes a row' is a discrete structural change - clamp cannot interpolate between different layouts. The honest split: continuous quantities (font sizes, spacing, gaps, widths within a range) go to clamp with viewport or container units; discrete states (1 column to 2, hide the nav) go to media or container queries. Teams that convert everything to fluid often end up fighting mid-range sizes where the layout needs a break, not a slide.
What are the classic clamp mistakes?
Three. Wrong wall order (clamp(3rem, 2vw, 1rem) - min above max - clamps to a constant; the function does not sort for you). Viewport-only preferred terms that overshoot on intermediate screens: 5vw is tiny at 400px and huge at 1600px, so the walls do all the work and the fluid middle barely matters - the fix is a bigger rem base inside the preferred term (calc(1rem + 2vw)) so it moves from a sane starting point. And px walls on typography, which freeze the clamp against the user's browser font setting. Every one is caught by the same review question: what does this clamp do at 360px, 800px and 1600px?