CSS clamp() and fluid type
Published: 2026-09-05
How CSS clamp() sets a floor, preferred value, and ceiling for fluid typography, and how to build a linear font-size ramp between viewport breakpoints.
Fluid type means font size scales smoothly with the viewport instead of jumping at media-query breakpoints. The usual CSS building block is clamp(min, preferred, max): the browser uses the preferred expression when it sits between the min and max, and clamps to the floor or ceiling otherwise. That one function replaces a pile of @media rules for linear size ramps.
What clamp() does
clamp() takes three values, in order:
| Argument | Role |
|---|---|
| Minimum | Hard floor — never smaller than this |
| Preferred | The “ideal” size (often a calc() that tracks vw) |
| Maximum | Hard ceiling — never larger than this |
font-size: clamp(1rem, 2.5vw, 1.5rem);
At a narrow viewport, 2.5vw may fall below 1rem, so the used size is 1rem. On a wide screen it may exceed 1.5rem, so the used size is 1.5rem. In between, the viewport-based preferred value wins.
The same pattern works for spacing, container widths, and other lengths—not only type. For typography, the preferred term is usually a linear function of viewport width so size grows (or shrinks) at a constant rate between two design widths.
Linear fluid type between two viewports
Designers often specify: “At 320px wide, body text is 16px; at 1280px, it is 24px; interpolate in between.” That is a straight line between two points:
size = minSize + (maxSize − minSize) × (vw − minVw) / (maxVw − minVw)
Below minVw you want the min size; above maxVw, the max size. Encoding that as CSS looks like:
font-size: clamp(
16px,
calc(16px + 8 * (100vw - 320px) / 960),
24px
);
Here 8 is the size delta (24 − 16) and 960 is the viewport span (1280 − 320). The middle calc() is the preferred value; clamp keeps it inside the floor and ceiling.
You can emit the same idea in rem if your root font size is known (commonly 16px): convert min/max sizes and the viewport bounds into rem, then keep the slope math consistent. Rem-based clamps respect user font-size settings better when the root scales; px clamps stay pixel-locked relative to the design’s absolute sizes.
px, rem, em, and viewport units
Fluid type sits on top of ordinary CSS length units. Quick reminders:
| Unit | Relative to | Typical use |
|---|---|---|
px |
Device/CSS pixels | Specs from design tools; hard floors/ceilings |
rem |
Root element (html) font size |
Scalable type that follows user/browser root size |
em |
Parent (or current) font size | Nested sizing; compounds if parents also change font-size |
vw / vh |
1% of viewport width / height | Preferred term in fluid ramps; also full-bleed layouts |
% |
Containing block (or font size for some properties) | Widths and spacing relative to a parent |
A common gotcha: putting only Nvw on font-size without clamp makes type tiny on phones and huge on ultrawide monitors. The min and max arguments exist to stop that. Another: mixing root assumptions—if you design in px but ship rem clamps, document the root size you assumed (e.g. 16px) so QA matches production.
Converting one-off values (24px → 1.5rem at a 16px root, or 48px → 2.5vw at a 1920px-wide preview) is separate from building a full ramp, but both show up in the same stylesheet workflow.
Practical tips and pitfalls
- Pick real breakpoints. Use the widths where your layout actually changes (content column, not arbitrary marketing numbers). Min and max font sizes should still pass readability checks at those extremes.
- Prefer one ramp per role. Body, H1, and captions can each have their own
clamp; sharing one formula for everything often looks odd at the edges. - Watch accessibility. Very aggressive slopes shrink text too far on small screens. Keep the minimum comfortable (often ≥
1remfor body copy) and test with browser zoom and larger default font sizes. - Container queries ≠ viewport fluid type.
cqw/ container-relative units scale with a container, not the whole window. Use them when a card or sidebar should drive size; usevwwhen the full viewport is the reference. - Safari and older engines. Modern browsers support
clamp()andcalc()with mixed units well; if you still support very old browsers, provide a staticfont-sizefallback above the clamp rule. - Rounding. Generated slopes often use many decimal places. That is fine for CSS; round only for readability, not in a way that breaks the endpoints.
Why generate clamps locally
Design tokens and brand type scales are not secret in the cryptographic sense, but pasting production CSS into a random “fluid type generator” still means sending your scale and breakpoints to someone else’s server. A client-side converter keeps the math in your tab—same privacy mindset as other local developer tools (Why “local only” matters for developer tools).
Try it on LocalTools
Open the CSS Unit Converter & Fluid Type tool:
- Use Fluid type to set min/max viewport widths and font sizes (px or rem input), choose px or rem output, and copy a ready
clamp(…)/calc(…)snippet with a live size preview. - Use Unit conversion for one-off px ↔ rem ↔ em ↔ vh/vw ↔ % with your root and viewport assumptions.
- Use Color when you need HEX / RGB / HSL beside the type work—still fully in-browser.
Nothing is uploaded; the snippet updates as you edit the numbers.
Related reading
- CSS Unit Converter & Fluid Type — generate clamps and convert units locally
- Why “local only” matters for developer tools