Fluid Type Scale Generator
Turn a base size, viewport range and modular ratio into a fluid clamp() type scale, exported as CSS custom-property tokens — entirely on this device.
| Step | Token | Size (px) | clamp() |
|---|---|---|---|
| -2 | --step--2 | 11.11 → 12.8 | clamp(0.6944rem, 0.6573rem + 0.1586vw, 0.8rem) |
| -1 | --step--1 | 13.33 → 16 | clamp(0.8333rem, 0.7746rem + 0.2504vw, 1rem) |
| 0 | --step-0 | 16 → 20 | clamp(1rem, 0.912rem + 0.3756vw, 1.25rem) |
| 1 | --step-1 | 19.2 → 25 | clamp(1.2rem, 1.0724rem + 0.5446vw, 1.5625rem) |
| 2 | --step-2 | 23.04 → 31.25 | clamp(1.44rem, 1.2593rem + 0.7709vw, 1.9531rem) |
| 3 | --step-3 | 27.65 → 39.06 | clamp(1.728rem, 1.4768rem + 1.0718vw, 2.4414rem) |
| 4 | --step-4 | 33.18 → 48.83 | clamp(2.0736rem, 1.7292rem + 1.4695vw, 3.0518rem) |
| 5 | --step-5 | 39.81 → 61.04 | clamp(2.4883rem, 2.0213rem + 1.9927vw, 3.8147rem) |
:root {
--step--2: clamp(0.6944rem, 0.6573rem + 0.1586vw, 0.8rem);
--step--1: clamp(0.8333rem, 0.7746rem + 0.2504vw, 1rem);
--step-0: clamp(1rem, 0.912rem + 0.3756vw, 1.25rem);
--step-1: clamp(1.2rem, 1.0724rem + 0.5446vw, 1.5625rem);
--step-2: clamp(1.44rem, 1.2593rem + 0.7709vw, 1.9531rem);
--step-3: clamp(1.728rem, 1.4768rem + 1.0718vw, 2.4414rem);
--step-4: clamp(2.0736rem, 1.7292rem + 1.4695vw, 3.0518rem);
--step-5: clamp(2.4883rem, 2.0213rem + 1.9927vw, 3.8147rem);
}- 1.2 is the Minor third
- 1.25 is the Major third
Press ? for shortcuts
Do it offline:$ node -p 's=(20-16)/(1440-375);i=16-s*375;"clamp("+(16/16)+"rem, "+Number((i/16).toFixed(4))+"rem + "+Number((s*100).toFixed(4))+"vw, "+(20/16)+"rem)"'
How to use it
- Set the base font size at the narrow viewport and the wide one.
- Give both viewport widths; the sample opens at 375px and 1440px.
- Pick a ratio or type your own, then set steps below and above the base.
- Leave root at 16 unless your stylesheet differs; rename the prefix if you like.
- Read the ladder, drag the preview, then copy or download as CSS or SCSS.
Enter a base font size at a narrow and a wide viewport, pick a modular ratio, and the tool multiplies the base by that ratio at each step. Each step whose two sizes differ becomes a CSS clamp() expression, and the set exports as custom-property tokens in CSS or SCSS. A slider previews the result, which is computed on this device.
How it works
A modular scale multiplies one base size by a ratio, step after step, and divides for negative steps. With the sample's 20px base and 1.25 ratio at the wide viewport, step 1 is 20 × 1.25 = 25px, step 2 is 20 × 1.25 × 1.25 = 31.25px, and step -1 is 20 ÷ 1.25 = 16px.
Each step then has two points, one per viewport, and the tool draws the line between them the way a clamp() solver does: slope from the size change over the viewport change, bounded so it never overshoots. Step 0 resolves to clamp(1rem, 0.912rem + 0.3756vw, 1.25rem).
The scale is emitted as custom-property declarations: a --step-n token per step inside :root, or $step-n variables for SCSS. Steps whose two sizes are equal print a plain rem value instead, which the tool notes. Because the sizes are rem, they follow the reader's browser font-size — raising the default from 16px to 20px scales every token, which WCAG 2.2 criterion 1.4.4, Resize Text, asks for.
Examples
CSS: base 16→20px, ratio 1.2→1.25, steps -2 to +5:root {
--step--2: clamp(0.6944rem, 0.6573rem + 0.1586vw, 0.8rem);
--step--1: clamp(0.8333rem, 0.7746rem + 0.2504vw, 1rem);
--step-0: clamp(1rem, 0.912rem + 0.3756vw, 1.25rem);
--step-1: clamp(1.2rem, 1.0724rem + 0.5446vw, 1.5625rem);
--step-2: clamp(1.44rem, 1.2593rem + 0.7709vw, 1.9531rem);
--step-3: clamp(1.728rem, 1.4768rem + 1.0718vw, 2.4414rem);
--step-4: clamp(2.0736rem, 1.7292rem + 1.4695vw, 3.0518rem);
--step-5: clamp(2.4883rem, 2.0213rem + 1.9927vw, 3.8147rem);
}The pre-filled sample: eight tokens, --step--2 to --step-5. The base --step-0 is clamp(1rem, 0.912rem + 0.3756vw, 1.25rem); 1.2 and 1.25 read as minor-third and major-third.
SCSS: base 16→20px, ratio 1.2→1.25, steps -1 to +2$step--1: clamp(0.8333rem, 0.7746rem + 0.2504vw, 1rem);
$step-0: clamp(1rem, 0.912rem + 0.3756vw, 1.25rem);
$step-1: clamp(1.2rem, 1.0724rem + 0.5446vw, 1.5625rem);
$step-2: clamp(1.44rem, 1.2593rem + 0.7709vw, 1.9531rem);The same ramp as SCSS: no :root wrapper, and $step-0 leads the $ variables.
Root 10, prefix fs: base 16→20px, ratio 1.333→1.414:root {
--fs--1: clamp(1.2003rem, 1.0932rem + 0.2677vw, 1.4144rem);
--fs-0: clamp(1.6rem, 1.4rem + 0.5vw, 2rem);
--fs-1: clamp(2.1328rem, 1.7852rem + 0.869vw, 2.828rem);
--fs-2: clamp(2.843rem, 2.2651rem + 1.4447vw, 3.9988rem);
}A root of 10 rewrites the rem math — the 16px base prints as --fs-0 clamp(1.6rem, 1.4rem + 0.5vw, 2rem) — and the prefix renames every token.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
A ratio of 1 leaves every step at the base
With both ratios at 1, every token equals the base clamp() and the tool reports that the scale has no size progression.
Steps may shrink as the screen grows
If the wide-end base or ratio is smaller, a step can grow on phones and shrink on desktops — a descent the tool notes, bounds still ordered low to high.
Very large scales hit the size ceiling
A 20px base at ratio 4 reaches 20480px by --step-5, past the ±10,000px limit; the generator refuses and names the first token over the line.
A one-step scale is just a clamp()
With both step counts at zero the ladder is the base alone — the generator sends you to the CSS clamp() Calculator for that case.
The name --step--2 has two hyphens on purpose
In --step--2 one hyphen joins the prefix and the other is the index's minus sign — odd, but a valid property name.
The root value rewrites the rem numbers
Because tokens are rem, the root sets their numbers: a 16px base is 1rem at root 16 and 1.6rem at root 10.
Common ratios carry names
1.2, 1.25 and 1.333 are musical intervals; 1.618 is the golden ratio. The label is cosmetic, and any ratio up to 4 works.
Container-query and logical units are out of scope
The fluid term uses vw; container units cqi and cqw, and the logical units vi and vb, are not emitted here.
Common errors
Min ratio must be greater than 0.- Zero or below cannot build a scale; each ratio field reports its own message.
Min ratio must be at most 4 (MAX_RATIO).- Ratios above 4 blow up the largest steps within a level or two, so 4 is the ceiling.
Positive steps must be at most 12 per side (MAX_STEPS_PER_SIDE).- Each side allows up to 12 steps and the ladder up to 24, so a runaway count cannot lock the page.
Token prefix must start with a letter or underscore and be 1 to 32 characters, using only letters, digits, hyphens or underscores.- The prefix becomes part of a property name, so characters CSS would reject are refused; a leading digit would break the SCSS form.
Step --step-5 is 20480px, past the ±10,000px limit (MAX_SIZE_PX) — reduce the ratio or step count.- Once a step passes ±10,000px the tool refuses, naming the token and size that overflowed.
Min viewport must be smaller than max- The base step is a clamp(), which needs a real range; equal or swapped widths raise this.
FAQ
What ratio should I pick?
Smaller ratios like 1.2 keep headings near body text and suit dense interfaces; larger ones such as 1.5 or the 1.618 golden ratio open a bold gap. Pairing a gentler narrow-end ratio with a stronger wide-end one is a common compromise.
How is this different from a clamp() calculator?
A clamp() calculator solves one fluid value between two sizes; this generator applies a ratio across many steps and returns a whole ladder of tokens. For a single value with no scale, the CSS clamp() Calculator is more direct.
Why rem tokens instead of px?
rem is a multiple of the root font size, the one typography control a reader owns, so rem tokens grow when someone enlarges their browser default; px tokens ignore that.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Rebuild the scale; it already refreshes on each valid edit.
- ⌘/Ctrl + C
- Copy the token block when nothing is selected; a focused number field is untouched.
- ⌘/Ctrl + Shift + C
- Copy the token block even with a selection active.
- ⌘/Ctrl + S
- Save the tokens as a snippet, overriding the browser's save dialog.
- t
- Switch the theme while no field is focused.
- ? or ⌘/Ctrl + /
- Show this page's keyboard-shortcut help.
- Esc
- Close the top dialog, leaving the fields as they were.