Fluid Typography with CSS clamp(): Build a Type Scale That Just Works (2026)
Fixed font sizes plus a handful of media-query breakpoints means text jumps in visible steps as the viewport resizes. clamp() replaces the jumps with continuous scaling — and the formula behind it is simpler than it looks.

What Is Fluid Typography?
Quick Answer
Fluid typography is font sizing that scales continuously with viewport width using clamp(), instead of jumping between fixed sizes at media-query breakpoints. Text is always an appropriately interpolated size for the current viewport, bounded by a minimum and maximum you control.
The traditional approach to responsive type sets a fixed font-size per breakpoint: 16px on mobile, 18px on tablet, 20px on desktop. It works, but it produces visible jumps exactly at each breakpoint, and it requires picking somewhat arbitrary breakpoint widths that may not match how your actual layout behaves. Fluid typography with clamp() replaces the step function with a straight line — text grows smoothly as the viewport widens, with no jump points at all.
The clamp() Function, Explained
Quick Answer
clamp(minimum, preferred, maximum) evaluates all three arguments and returns the preferred value — unless it falls outside the minimum-maximum range, in which case the nearer bound wins. For fluid type, the preferred value is a viewport-relative expression that changes continuously as the browser resizes.
/* clamp(minimum, preferred, maximum) */h1 { font-size: clamp(1.75rem, 4vw + 1rem, 3.5rem);} /* Below the vw breakpoint where "preferred" would go under 1.75rem, the browser uses 1.75rem instead — and above the point where it would exceed 3.5rem, it caps at 3.5rem. */The middle argument is where the fluidity actually comes from. A plain 4vw alone would scale infinitely in both directions, becoming illegibly small on a phone or absurdly large on an ultrawide monitor. clamp() keeps that viewport-relative growth but caps it at sane bounds on both ends — which is exactly why it's the tool for this job rather than vw alone.
The Formula Behind the Preferred Value
Quick Answer
Given a min size, max size, min viewport, and max viewport (all in px), the slope is (maxSize - minSize) / (maxViewport - minViewport), and the intersection is minSize - minViewport * slope. The preferred value is then {intersection}px + {slope * 100}vw — a straight linear interpolation between your two size/viewport pairs.
This is genuinely just the two-point form of a line — the same math as finding the equation of a line through two (x, y) points, where x is viewport width and y is font size. Once you have the slope and intersection, the vw unit does the interpolation automatically as the browser resizes, with zero JavaScript.
/* The linear interpolation formula behind a fluid clamp() Given: minSize, maxSize — the font sizes at each end, in px minViewport, maxViewport — the viewport widths at each end, in px slope = (maxSize - minSize) / (maxViewport - minViewport) intersection = minSize - minViewport * slope preferred value = {intersection}px + {slope * 100}vw*/ /* Example: 16px at a 320px viewport, scaling up to 24px at 1280px *//* slope = (24 - 16) / (1280 - 320) = 0.00833... *//* intersection = 16 - 320 * 0.00833 = 13.33 */ .fluid-text { font-size: clamp(1rem, 0.833rem + 0.833vw, 1.5rem);}Doing this arithmetic by hand for every text style in a design system gets tedious fast, which is exactly the kind of repetitive calculation a small tool should do for you — the Fluid clamp() Calculator takes your min/max size and viewport inputs and outputs the exact CSS, slope and intersection already done.
Building a Full Fluid Type Scale
Quick Answer
Apply the same clamp() formula to every level of your type scale — body text, h3, h2, h1 — each with its own min/max size pair but a shared min/max viewport range, then expose each as a CSS custom property so the scale is defined once and reused everywhere.
The real payoff of fluid typography shows up once it's applied consistently across a whole scale, not just a hero heading. Defining each level as a custom property keeps the scale centralized and makes it trivial to reference from any component.
:root { /* Each pair: min size at 320px viewport → max size at 1280px */ --fs-body: clamp(1rem, 0.958rem + 0.208vw, 1.125rem); /* 16px → 18px */ --fs-h3: clamp(1.25rem, 1.167rem + 0.417vw, 1.5rem); /* 20px → 24px */ --fs-h2: clamp(1.5rem, 1.25rem + 1.25vw, 2.25rem); /* 24px → 36px */ --fs-h1: clamp(2rem, 1.5rem + 2.5vw, 3.5rem); /* 32px → 56px */} body { font-size: var(--fs-body); }h1 { font-size: var(--fs-h1); }h2 { font-size: var(--fs-h2); }h3 { font-size: var(--fs-h3); }Recomputing four or more slope/intersection pairs by hand, though, is exactly the kind of chore worth skipping — the Typography Scale Generator builds an entire fluid scale like this one visually, across 8 different ratios, in one pass.
Fluid Spacing, Not Just Font Size
Quick Answer
The exact same clamp() technique works for any length-valued property — padding, margin, gap, width. Fluid spacing that scales smoothly with the viewport, instead of jumping at breakpoints, is one of the most underused applications of the same formula.
Most teams stop at applying clamp()to font sizes and go back to fixed values or media queries for everything else — but the interpolation math doesn't care what property it's attached to. A card's internal padding, the gap in a flex layout, or the vertical rhythm between page sections all benefit from the same smooth scaling.
/* The exact same clamp() technique applied to spacing — a card's padding that scales with the viewport instead of jumping at a breakpoint */.card { padding: clamp(1rem, 0.6rem + 2vw, 2.5rem); gap: clamp(0.75rem, 0.5rem + 1vw, 1.5rem);} .section { margin-block: clamp(2rem, 1rem + 5vw, 6rem);}If you're converting an existing fixed-spacing scale to fluid values and want to sanity-check what a given px figure actually looks like in rem or vw before committing to it, the CSS Units Converter handles that instantly.
Browser Support
Quick Answer
clamp() has been supported in all major browsers since 2020 — Chrome 79+, Firefox 75+, Safari 13.1+ — with global support above 96% as of 2026. It's safe to use as your primary sizing mechanism without a fallback in virtually any production project.
Unlike some of the more recently shipped CSS features covered elsewhere on this site, clamp() is not a bleeding-edge feature — it's been broadly supported for several years and is safe to rely on directly, with no @supports guard or fallback value required for the overwhelming majority of production audiences.
Frequently Asked Questions
What is fluid typography in CSS?
Font sizing that scales continuously with viewport width using clamp(), rather than jumping between fixed sizes at media-query breakpoints.
How does the CSS clamp() function work?
clamp(MIN, PREFERRED, MAX) returns PREFERRED unless it falls outside the MIN-MAX range, in which case the nearer bound is used. For fluid type, PREFERRED is a viewport-relative expression that changes continuously.
What is the formula for the preferred value?
slope = (maxSize - minSize) / (maxViewport - minViewport); intersection = minSize - minViewport * slope. The preferred value is intersection + (slope * 100)vw — linear interpolation between two size/viewport pairs.
Does clamp() have good browser support?
Yes — supported since 2020 in all major browsers, with global support above 96% in 2026. Safe to use without a fallback.
Can clamp() be used for spacing, not just font size?
Yes — the same formula applies to padding, margin, gap, width, or any length-valued property.
Is there a free clamp() calculator?
Yes — the CSSAWWWARDS Fluid clamp() Calculator computes the full declaration from your inputs, and the Typography Scale Generator builds a whole scale at once. Both free, no signup.