Bookmarks for Devs

CSS clamp() calculator for fluid typography

Generate a responsive CSS clamp() font size from a minimum and maximum size and the viewport range they should grow across — with the slope and intercept shown, a live preview, and the rendered size at every common screen width. Free, no sign-up.

Free · no sign-up · runs in your browser

Viewport widths are always in px.

Live preview

Resize the window and this line grows with it — no media queries.

The line behind it

Slope
(24 − 16) ÷ (1280 − 320)
= 0.8333vw
Intercept
16 − 0.0083 × 320
= 0.8333rem

Rendered size

ViewportSize
320px16pxfluid
480px17.33pxfluid
768px19.73pxfluid
1024px21.87pxfluid
1280px24pxfluid
1536px24pxpinned to max

Copy the CSS

Declaration

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

Custom property

:root {
  --step-0: clamp(1rem, 0.8333rem + 0.8333vw, 1.5rem);
}

0.8333rem + 0.8333vw

Fluid typography replaces a stack of font-size media queries with a single clamp() declaration: the text grows smoothly with the viewport between a floor and a ceiling you choose. The hard part is the middle argument, which is the equation of a straight line through your two anchor points — this works it out, shows you the arithmetic rather than hiding it, and tells you what the text actually measures at 320px through 1536px so you can see the small end before shipping it.

How it works

  1. 01Your two font sizes and two viewport widths define two points on a graph: size at the narrow end, and size at the wide end.
  2. 02The slope is the rise over the run — (max size − min size) ÷ (max viewport − min viewport) — which is how many pixels the text grows per pixel of viewport. Multiplied by 100 it becomes a vw value, because 1vw is one hundredth of the viewport.
  3. 03The intercept is where that line would cross a zero-width viewport: min size − slope × min viewport. It is usually negative, which is correct and not a mistake — it is what pulls the line down so it passes through your minimum at the right width.
  4. 04Those two numbers become the middle argument, and your sizes become the outer two: clamp(min, intercept + slope×100vw, max). Below the minimum viewport the text is pinned to the floor, above the maximum to the ceiling, and in between it is on the line.
  5. 05The output is always in rem, whichever unit you typed. A font size in px ignores the reader's browser text-size setting, so a fluid scale built in px cannot be zoomed — that is an accessibility bug, not a style choice.
  6. 06The table shows what the declaration resolves to at common viewport widths, and marks whether each one is on the line or pinned at an end.

Use cases

  • Replacing three or four font-size media queries per heading level with one declaration.
  • Building a fluid type scale as CSS custom properties, one clamp() per step.
  • Checking that a heading does not collapse to something unreadable on a 320px phone before it ships.
  • Fluid spacing as well as type — the same maths works for margin, padding, gap and any other length.
  • Setting a container or measure that grows with the viewport but stops at a comfortable reading width.
  • Sanity-checking a clamp() a designer or an AI wrote, by reading the slope and the rendered sizes back.

Frequently asked questions

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

Take your minimum size at your narrowest viewport and your maximum size at your widest. The slope is (max size − min size) ÷ (max viewport − min viewport), expressed in vw by multiplying by 100. The intercept is min size − slope × min viewport. The result is clamp(min, intercept + slope×100vw, max). Enter the four numbers above and it is worked out for you, with the slope and intercept shown.

Why is the middle value of my clamp() negative?

The intercept is where the line would sit at a viewport of zero width, which is off the left edge of any real screen — so for most fluid type it is a negative rem value. That is expected. It is the number that makes the line pass through your minimum size at your minimum viewport rather than at 0px, and the clamp's first argument stops it ever being used.

Should I use px or rem in clamp()?

Use rem for the sizes. A font size expressed in px does not respond when a reader changes their browser's default text size, so a px-based fluid scale is unzoomable — a real accessibility failure, and one that clamp() makes easy to ship by accident. Viewport widths are still entered in px here because that is how screens are measured; only the output is converted.

Does clamp() work without media queries?

Yes, that is the point. clamp() interpolates continuously with the viewport, so one declaration covers every width instead of stepping between breakpoints. It has full support in every current browser. Media queries remain useful for layout changes — a column count, a hidden element — but for a size that simply grows, clamp() replaces them.

What happens if the minimum is larger than the maximum?

CSS resolves clamp(min, val, max) as max(min, min(val, max)), so when the bounds cross, the minimum wins at every viewport and the size never changes. The calculator flags this rather than silently emitting a declaration that looks fluid but is not.

Can I use clamp() for spacing and widths too?

Yes. Nothing in the formula is specific to type — it produces a length. The same output works for margin, padding, gap, width, max-width and border-radius. For spacing, pick your two anchor values in the same units and read the result the same way.

Related resources

Related reading

More tools

Tailwind CSS color palette generator

Open →

Turn one hex code into a full Tailwind color scale — 11 OKLCH-tuned shades from 50 to 950, with contrast ratios, ready to paste into Tailwind v4's @theme block or a v3 config. Free, no sign-up, runs in your browser.

SVG to JSX converter for React components

Open →

Paste an SVG and get a React component back — attributes camelCased, class turned into className, style strings converted to objects, xmlns removed, with optional currentColor, a size prop and TypeScript output. Runs entirely in your browser; nothing is uploaded.

Meta tag generator with Google SERP preview

Open →

Fill in a title, description, canonical and Open Graph image and get the complete <head> snippet — with a live Google result preview that measures your title and description in pixels, not characters, so you can see exactly where they will be cut.

Favicon generator — .ico, PNG set and manifest

Open →

Turn a PNG or SVG, or just a couple of letters, into the full favicon set: 16, 32, 48, 180, 192 and 512 PNGs, a real multi-size favicon.ico, a web app manifest and the <head> tags. Everything runs in your browser — nothing is uploaded.

JSON-LD schema generator and validator

Open →

Build valid JSON-LD structured data for Article, FAQPage, Product, Organization and BreadcrumbList from a form, or paste existing markup to have it pretty-printed and checked for the mistakes that stop a rich result appearing. Free, runs in your browser.

robots.txt generator with validation

Open →

Build a robots.txt from user-agent groups, allow and disallow rules, crawl-delay and sitemap URLs — with presets for allowing everything, blocking AI crawlers, or locking down a staging site, and warnings for the mistakes that quietly block your whole site.

UTM link builder and campaign URL generator

Open →

Build correctly encoded UTM tracking links from a URL and your source, medium and campaign — with the existing query string and fragment preserved, values properly percent-encoded, and warnings for the capitalisation and spacing that split one campaign across several rows in an analytics report.

Colour contrast checker with WCAG suggestions

Open →

Check any two colours against WCAG 2 — normal text, large text and UI components — see the ratio and live samples, and get the nearest passing colour when a pair fails, adjusted in OKLCH so the hue stays yours. Free, runs in your browser.

Image converter — WebP, AVIF, JPEG and PNG

Open →

Convert and resize images to WebP, AVIF, JPEG or PNG at the quality you choose, see exactly how many bytes each one saved, and download them one at a time or as a zip. Everything happens in your browser — no image is uploaded.

JSON formatter and validator — free, in your browser

Open →

Format, minify and validate JSON in your browser. Broken documents get the exact line and column of the error. Nothing is uploaded, and there is no size limit but your machine.

JSON to TypeScript — generate interfaces from a payload

Open →

Paste a JSON payload and get TypeScript interfaces: merged array shapes, optional properties, and real unions instead of any. Runs in your browser — nothing is uploaded.

OG image generator — free 1200×630 social cards

Open →

Generate an Open Graph image for any page: type a title, pick a theme, download a 1200×630 PNG. Runs entirely in your browser — no account, no upload, no watermark.