CSS clamp() Generator for Fluid Typography

Turn a min/max pixel size and two viewport widths into a fluid clamp() in rem, with a live type preview across the viewport range.

Fluid CSS clamp() generator

clamp(1rem, 0.8333rem + 0.8333vw, 1.5rem)
font-size: clamp(1rem, 0.8333rem + 0.8333vw, 1.5rem);

Narrower than 320px the size stays 16px; wider than 1280px it stays 24px; in between it slides in a straight line from one to the other — the "…rem + …vw" part of the value is that line.

Show the working

Slope: (24 − 16) ÷ (1280 − 320) = 0.0083 px of size for every px of width — 0.8333vw in the value.

Intercept: 16 − 320 × 0.0083 = 13.3333px — the size the line gives at zero width.

Preferred value: 13.3333px + 0.0083 × the width. It is used between the two bounds and held at the nearer bound outside them.

Preview

The quick brown fox jumps over the lazy dog
Type scale

Body text takes the min and max sizes above; each heading is one step of the ratio larger than the one below it.

:root {
  --fs-body: clamp(1rem, 0.8333rem + 0.8333vw, 1.5rem); /* 16px → 24px */
  --fs-h6: clamp(1.2rem, 0.975rem + 1.125vw, 1.875rem); /* 19.2px → 30px */
  --fs-h5: clamp(1.44rem, 1.1388rem + 1.5063vw, 2.3438rem); /* 23.04px → 37.5px */
  --fs-h4: clamp(1.728rem, 1.3274rem + 2.0028vw, 2.9297rem); /* 27.65px → 46.88px */
  --fs-h3: clamp(2.0736rem, 1.5441rem + 2.6475vw, 3.6621rem); /* 33.18px → 58.59px */
  --fs-h2: clamp(2.4883rem, 1.7919rem + 3.4822vw, 4.5776rem); /* 39.81px → 73.24px */
  --fs-h1: clamp(2.986rem, 2.074rem + 4.5601vw, 5.722rem); /* 47.78px → 91.55px */
}
clamp(1rem, 0.8333rem + 0.8333vw, 1.5rem)

What this CSS clamp() generator does

Enter a minimum and maximum size in pixels, the viewport widths where each size should apply, and your root font size, and this tool builds a ready-to-paste clamp() value for fluid typography or spacing. It computes the linear slope between your two breakpoints, converts pixels to rem using your root font size, and outputs clamp(minRem, yRem + slopeVw, maxRem). The result scales smoothly with the viewport and clamps at your chosen bounds — no media queries required. Under the result, a preview draws a line of type at the exact size the value resolves to, and a viewport-width slider runs past both breakpoints so you can see where the size stops growing.

How the math works

The slope is (maxPx - minPx) / (maxVw - minVw), expressed in the unit picked under “Grows with” — vw unless you change it — so the value grows with the viewport width, or with the container’s for cqw and cqi. The intersection term, -minVw * slope + minPx, is the fixed rem offset that anchors the line so it passes through your minimum size at the minimum viewport and your maximum size at the maximum viewport. Values are rounded to four decimals to stay accurate without bloating your CSS. Below the minimum viewport the size holds at the minimum, and above the maximum viewport it holds at the maximum. Open “Show the working” under the value to see these numbers for what you typed — the slope in px per px of width and as the figure in the value, the intercept, and the preferred value as intercept + slope × width — worked by the same calculation that writes the value, so the two cannot disagree.

Frequently asked questions

Why does the tool convert pixels to rem?

Using rem for the clamped bounds keeps your fluid sizes tied to the user's root font size, which respects browser and accessibility zoom settings. The pixel inputs are just an easy way to describe the design; the output is expressed in rem and, unless “Grows with” says otherwise, vw.

Do I still need media queries?

No. A single clamp() value scales the size continuously between your min and max viewports and locks at the bounds outside that range, so you usually do not need breakpoint media queries for that property.

Can I work in rem, or generate a whole type scale?

Yes. The sizes can be typed in px or rem and the value written in either. Type scale writes a clamp() for body text and every heading level from a ratio at each end of the viewport range, with a button to copy them all.

Can it use container or dynamic viewport units, or write the value as a token or a Tailwind class?

Yes. “Grows with” picks the unit the value scales by: vw, svw, lvw, dvw, vi, cqw or cqi. Pick a container unit and the width fields and the preview slider are renamed for the container, with a note that the parent needs container-type. “Use it for” sets the property the copied line is written for — font-size, padding, gap and more, or “Other…” for one you type — and “Write it as” writes that line as a declaration, a CSS custom property, an SCSS variable or a Tailwind class, the named forms taking their name from the Name box.

Can I see how the clamp() value was worked out?

Yes. Open “Show the working” under the value. It prints the slope as (max − min) ÷ (max width − min width) with your numbers — in px of size per px of width, and as the figure that appears in the value — then the intercept, min − min width × slope, and the preferred value as intercept + slope × width. The working and the value come from the same calculation, so they cannot disagree.