Skip to content

Frontend

Fluid Typography with CSS clamp(): The Formula, Zoom and Tailwind (2026)

How to build fluid font sizes and spacing with CSS clamp(): the slope and intercept formula, a worked example, the zoom rule for accessibility, and Tailwind usage.

Fluid type with clamp() is one declaration: font-size: clamp(1.5rem, 1rem + 2.5vw, 3rem). The text is never smaller than the first value, never larger than the last, and in between it grows with the viewport along a straight line. The middle value is the only hard part: it is the equation of the line through your two anchor points.

The CSS clamp calculator works that line out from four numbers and shows the slope, the intercept and the size at common screen widths. Below is the formula by hand, the accessibility rule that keeps it zoomable, and how to use it in Tailwind. Specs were checked against MDN, W3C and Tailwind documentation on 13 November 2026.

What clamp() does

clamp(min, val, max) takes a minimum, a preferred value and a maximum. MDN states it resolves as max(MIN, min(VAL, MAX)), so the preferred value is used while it sits between the bounds, otherwise the nearest bound wins. It is marked Baseline widely available, in browsers since July 2020, and works for any length, not just font-size.

The formula

Pick two anchor points: a size at a narrow viewport and a size at a wide one.

StepFormula
Slope(max size − min size) ÷ (max viewport − min viewport)
Slope in vwslope × 100
Interceptmin size − slope × min viewport
Resultclamp(min, intercept + slope-in-vw, max)

Worked example: a heading that is 24 px at a 320 px viewport and 48 px at 1280 px.

  • Slope = (48 − 24) ÷ (1280 − 320) = 0.025, which is 2.5vw.
  • Intercept = 24 − 0.025 × 320 = 16 px, which is 1rem at a 16 px root size.
  • Result: clamp(1.5rem, 1rem + 2.5vw, 3rem).

The intercept is often negative for other inputs. That is correct: it is where the line would cross a zero-width viewport, and it pulls the line through your minimum at the right width. The calculator output for this example resolves to 24 px at 320, 35.2 px at 768, 41.6 px at 1024 and 48 px at 1280, and stays at 48 beyond that.

Use the calculator

  1. Open the CSS clamp calculator.
  2. Enter the minimum and maximum size, and the minimum and maximum viewport width (viewports are always in px).
  3. Copy the clamp() it prints. The output is in rem whichever unit you typed.
  4. Read the table of sizes at 320 to 1536 px and check the small end before shipping.

It warns when the minimum is not smaller than the maximum (then the size never changes), when the viewport range is empty or backwards, and when the minimum is under 16 px.

Accessibility: keep it zoomable

Fluid type is easy to make unreadable for people who zoom or enlarge text. Two documented rules:

  • Bound it in relative units, with room to grow. MDN says that when clamp() controls text size, the maximum should be a relative length unit no less than twice the minimum, for example clamp(1rem, 2.5vw, 2rem). This helps text scale to at least 200% when the page is zoomed. The example above passes: 3rem is twice 1.5rem.
  • Never size text with vw alone. WCAG 2.2 success criterion 1.4.4 (Level AA) requires that text can be resized up to 200 percent without loss of content or functionality. W3C lists technique F94 as a failure: sizing text with viewport units, such as font-size: 1vw, so it does not rescale.

That is why a px minimum and maximum are a bad idea. Use rem for the bounds and the constant part of the middle term, and keep the spread between min and max at 2× or more. Test by zooming the page to 200% and by raising the browser's default text size.

Tailwind usage

Tailwind needs underscores for spaces inside square brackets; it converts them at build time. So a one-off size is:

<h1 class="text-[clamp(1.5rem,1rem_+_2.5vw,3rem)] font-bold">Fluid heading</h1>

For reuse, define a theme variable. Tailwind's --text-* namespace creates font-size utilities, so --text-tiny becomes text-tiny. A clamp() value follows the same pattern:

@import "tailwindcss";

@theme {
  --text-fluid-h1: clamp(1.5rem, 1rem + 2.5vw, 3rem);
  --text-fluid-h1--line-height: 1.1;
}
<h1 class="text-fluid-h1">Fluid heading</h1>

The --text-*--line-height companion variable is documented in Tailwind's font-size page. The rest of your Tailwind classes, md: breakpoints included, still work alongside it.

Fluid spacing

Nothing in the formula is specific to type: clamp() returns a length. For padding that grows from 16 px at 320 px to 32 px at 1280 px, the calculator gives clamp(1rem, 0.6667rem + 1.6667vw, 2rem). In Tailwind:

<section class="p-[clamp(1rem,0.6667rem_+_1.6667vw,2rem)]">...</section>

The same output works for margin, gap, width, max-width and border-radius.

Common mistakes

  • Min larger than max. Per the resolve rule, the minimum wins everywhere and nothing is fluid.
  • Viewport units only. font-size: 1vw fails WCAG technique F94. Always include a rem term and bounds.
  • A max less than 2× the min. It may not reach 200% when zoomed, which MDN warns about.
  • Tiny minimums. A heading that collapses to 12 px on a phone is a design bug; check the 320 px row.
  • Spaces in Tailwind brackets. Write 1rem_+_2.5vw; Tailwind turns the underscores into spaces.

Picking the typeface is a separate step: Best Free Fonts and Fonts In Use are good places to start. More utilities for front-end work are in frontend tools worth bookmarking and the Frontend directory. The other free generators are in the toolbox.

FAQ

How do I calculate a clamp() for fluid font size?

Compute the slope as (max − min) ÷ (max viewport − min viewport), multiply by 100 for vw, and the intercept as min − slope × min viewport. Or enter the four values in the calculator.

Is clamp() accessible?

Yes, if the bounds are in rem and the maximum is at least twice the minimum, as MDN advises. Avoid viewport units alone.

Does clamp() replace media queries?

For a size that only grows smoothly, yes. Keep media queries for layout changes such as column counts.

Sources