Colour CSS

CSS clamp generator

Type scales with the viewport

Generated in your browser · nothing is uploaded

Live preview · rem intercept, not px

Builds a clamp() that moves a size linearly between two viewport widths; a small size at a small screen, a large size at a large one, and a straight line between them. Drag the preview to see the value at any width.

How to use the css clamp generator

1 Set the smallest size and the viewport width at which it should stop shrinking.
2 Set the largest size and the width at which it should stop growing.
3 Drag the preview slider across the range to check the middle, which is where a bad pair of endpoints shows up.
4 Copy the clamp(), which needs no calc() around it.
5 Reuse the same two widths across every fluid size on the site so they scale together.

The middle term of a clamp is nothing more exotic than the equation of a line through two points. Slope is the size difference divided by the width difference; the intercept is where that line would cross a viewport of zero width. Take the default here, 16px at 320px growing to 32px at 1280px. The slope is 16 ÷ 960, which is 0.016667 pixels of type per pixel of viewport, and a viewport pixel is one hundredth of a vw, so the slope becomes 1.667vw. The intercept is 16 − (320 × 0.016667), which is 10.667px, or 0.667rem at a 16px root. Put them together and you have clamp(1rem, 0.667rem + 1.667vw, 2rem). Every fluid-type clamp looks like an arbitrary pair of numbers for that reason: they are the two coefficients of a line, and nothing else.

Writing the intercept in rem rather than px is deliberate, and it is the part most hand-written clamps get wrong. A viewport unit answers to the window and to nothing else. It does not move when a reader raises their browser’s default font size, so a size built purely from vw quietly overrides a setting somebody chose on purpose. WCAG 1.4.4 requires that text can be resized up to 200 per cent without losing content or function, and a rem term keeps the reader’s setting inside the equation. The minimum and maximum are in rem here too, which matters even more: at the small and large ends of the range the value is pure rem, so their setting has full effect exactly where the text is smallest.

The function needs no calc() around that sum, and this surprises people who have written CSS for a while. clamp(), min() and max() are themselves maths functions, and each of their arguments is parsed as a calculation, so 0.667rem + 1.667vw is valid where it stands. It is also worth being precise about what the three arguments do: clamp(a, b, c) is defined as max(a, min(b, c)), so the value is held at the minimum below the range and at the maximum above it, and if you accidentally set a minimum larger than the maximum, the minimum wins.

Two cautions on choosing the range. A very steep slope makes text visibly jump while a window is dragged, and a very shallow one makes the whole exercise pointless; keeping the largest size under roughly twice the smallest avoids both. And the conversion here assumes a 16px root, which is the browser default. If your stylesheet sets html { font-size: 62.5% } to make a rem equal 10px, every rem figure generated here is wrong by a factor of 1.6, and that old trick is worth abandoning rather than compensating for.

What people use it for

  • Sizing a heading that has to work at 375px and at 1440px
  • Replacing three font-size media queries with one declaration
  • Keeping fluid type responsive to a reader’s own browser font setting
  • Working out the rem and vw coefficients behind a size range
  • Scaling section padding or a gutter with the viewport rather than the text

Questions

Because it is the equation of a line. The rem term is the intercept and the vw term is the slope, and together they draw a straight line between your two endpoints.

MDN, clamp()WCAG 2.2, Success Criterion 1.4.4 Resize Text
Was this tool any good?
Internal signal only · I use it to find the tools worth rebuilding