What this does
Give this calculator four numbers — the viewport width where scaling should
start, the width where it should stop, and the size you want at each — and it
solves the straight line through those two points and writes it as a CSS
clamp(). A fifth field sets the root font size used to express
the intercept in rem, defaulting to 16 px. The result is
applied live to a sample paragraph below the fields, so resizing your browser
window shows the curve working.
The defaults are 320 px → 1280 px and 16 px → 20 px, which produce:
font-size: clamp(16px, 0.9167rem + 0.4167vw, 20px); How is the middle value calculated?
It is ordinary two-point line fitting. The slope is
(maxSize − minSize) / (maxVw − minVw) in pixels per
pixel; multiplied by 100 it becomes a vw coefficient, since
1vw is one hundredth of the viewport. The intercept is
minSize − slope × minVw in pixels, divided by the
root font size to give rem. With the defaults that is
4 ÷ 960 = 0.0041667 px/px → 0.4167vw, and
16 − 1.3333 = 14.6667 px → 0.9167rem. Both
numbers are shown under the preview so you can sanity-check them.
Why include a rem term at all — why not pure vw?
A pure vw value is proportional to the viewport, so it can only
pass through your two points if the line happens to go through the origin. It
almost never does. The rem intercept is what lets the line hit
16 px at 320 px wide and 20 px at 1280 px wide instead of
something arbitrary. It also matters for accessibility: a size expressed only
in vw ignores the user's browser font-size setting entirely,
while the rem half of this expression responds to it.
How do I build a fluid type scale?
- Fix one viewport range and reuse it for every step — 320 to 1280 is a sensible default. Consistent endpoints keep the whole scale in proportion.
- Enter the min and max size for your body text first and copy the result.
- Change only the two size fields for each further step: small text, then h3, h2, h1. Sizes accept half-pixel steps up to 500 px.
- Give the larger steps a wider min-to-max spread than the body — headings should grow faster than paragraphs, or the page looks flat on desktop.
- Paste each declaration into a custom property so the scale lives in one place.
When should I change the root font field?
Only when your page genuinely sets html { font-size } to
something other than 16 px. The field accepts 8 to 32 px and it
changes how the intercept is written, not what the browser does — the browser
resolves rem against the real root size at render time. If the
two disagree, your line will not pass through the points you asked for.
Why is my value not changing when I resize?
Outside the viewport range the clamp() bounds take over and the
value is flat by design — that is the point of the min and max arguments.
Check you are resizing within the range you entered. If the CSS box instead
reads /* min viewport must be < max */, the two viewport
fields are the wrong way round; the tool refuses to divide by a zero or
negative range.
What else pairs with this?
Work out the px and rem values for each step in the CSS unit converter, and use the same fluid idea on spacing and elevation alongside the border-radius and box-shadow generators. Everything is computed in the page.