Fluid CSS clamp() generator
Write clamp() values that scale font sizes or spacing smoothly between two viewport widths, for one property or a whole type scale.
A clear answer. Here’s how.
Between the two viewport widths the size follows a straight line: slope = (maximum size − minimum size) ÷ (maximum viewport − minimum viewport) and intercept = minimum size − slope × minimum viewport, all in px. Because 1vw is 1% of the viewport width, the preferred value is intercept + (slope × 100)vw, and clamp(smaller size, preferred, larger size) holds it flat outside the range. Lengths in rem are converted with the root size you give; the output writes the sizes and the intercept in rem or px and the slope in vw, each rounded to 4 decimal places, which changes the size by far less than 0.01 px at ordinary widths. A size that shrinks as the screen widens (a negative slope) works too. In a type scale, step n is the base size times the ratio to the power n, worked out separately at each viewport (the method popularised by Utopia), and each step gets its own clamp(). The vw part does not grow when a reader zooms, so a value made mostly of vw can stop text reaching 200% zoom (WCAG 1.4.4); keep a large rem part and test. This writes CSS only; it does not check how a typeface looks at each size.
How this is checked
5 reference checks passed These 5 cases were run when this page was built, on 20 October 2026, and all reproduce within the stated tolerance. The same cases are part of the automated tests that run on every change to Toolmoz. Engine version 1.
See the checks and where each expected answer comes from
Case 1
- Inputs
- The tool’s default inputs
- Expected, and what Toolmoz gave
- Slope (vw) expected 0.8695652173913043, Toolmoz 0.8695652173913043Intercept (px) expected 13.217391304347826, Toolmoz 13.217391304347826clamp() expected clamp(1rem, 0.8261rem + 0.8696vw, 1.5rem), Toolmoz clamp(1rem, 0.8261rem + 0.8696vw, 1.5rem)
- Where the expected answer comes from
- By hand: slope = (24 − 16) / (1240 − 320) = 8 / 920 = 0.0086957, so 0.8696vw; intercept = 16 − 0.0086957 × 320 = 13.2174 px = 0.8261 rem at 16 px
- Allowed difference
- ±1e-9
Case 2
- Inputs
- Size at the minimum viewport 36pxSize at the maximum viewport 52pxMinimum viewport width 600pxMaximum viewport width 1400px
- Expected, and what Toolmoz gave
- Slope (vw) expected 2, Toolmoz 2Intercept (px) expected 24, Toolmoz 24clamp() expected clamp(2.25rem, 1.5rem + 2vw, 3.25rem), Toolmoz clamp(2.25rem, 1.5rem + 2vw, 3.25rem)
- Where the expected answer comes from
- Smashing Magazine worked example: v = 2 and r = 24 px = 1.5 rem, written there as clamp(2.25rem, 2vw + 1.5rem, 3.25rem)
- Allowed difference
- ±1e-9
Case 3
- Inputs
- Size at the minimum viewport 1remSize at the maximum viewport 2remMinimum viewport width 320pxMaximum viewport width 1440px
- Expected, and what Toolmoz gave
- Slope (vw) expected 1.4285714285714286, Toolmoz 1.4285714285714286clamp() expected clamp(1rem, 0.7143rem + 1.4286vw, 2rem), Toolmoz clamp(1rem, 0.7143rem + 1.4286vw, 2rem)
- Where the expected answer comes from
- Utopia clamp() article: 1rem to 2rem from 320 px to 1440 px is clamp(1rem, 0.7143rem + 1.4286vw, 2rem)
- Allowed difference
- ±1e-9
Case 4
- Inputs
- Generate scaleSize at the minimum viewport 16pxSize at the maximum viewport 20pxScale ratio at the minimum viewport 1.2Scale ratio at the maximum viewport 1.25Steps above the base 2Steps below the base 1
- Expected, and what Toolmoz gave
- Steps expected 4, Toolmoz 4Slope of step 0 (vw) expected 0.43478260869565216, Toolmoz 0.43478260869565216Largest step at maximum viewport (px) expected 31.25, Toolmoz 31.25Smallest step at minimum viewport (px) expected 13.333333333333334, Toolmoz 13.333333333333334
- Where the expected answer comes from
- By hand: steps −1 to 2 make 4; step 0 slope (20 − 16) / 920 × 100 = 0.43478vw; step 2 at 1240 px is 20 × 1.25² = 31.25 px; step −1 at 320 px is 16 / 1.2 = 13.3333 px
- Allowed difference
- ±1e-9
Case 5
- Inputs
- Size at the minimum viewport 24pxSize at the maximum viewport 16px
- Expected, and what Toolmoz gave
- Slope (vw) expected -0.8695652173913043, Toolmoz -0.8695652173913043Intercept (px) expected 26.782608695652176, Toolmoz 26.782608695652172clamp() expected clamp(1rem, 1.6739rem - 0.8696vw, 1.5rem), Toolmoz clamp(1rem, 1.6739rem - 0.8696vw, 1.5rem)
- Where the expected answer comes from
- By hand, a shrinking size: slope = (16 − 24) / 920 = −0.0086957; intercept = 24 + 0.0086957 × 320 = 26.7826 px = 1.6739 rem; clamp keeps the smaller size first
- Allowed difference
- ±1e-9
What this shows: the engine reproduces independently worked values for these cases. It does not prove every possible input is right. To test an answer you were given, see how to check a number; to see what is and is not checked across Toolmoz, see the accuracy ledger.
See a worked example
Worked example
A fixed demonstration, separate from the values you enter above.
- Generate
- One fluid value
- Size at the minimum viewport
- 16px
- Size at the maximum viewport
- 24px
- Minimum viewport width
- 320px
- Maximum viewport width
- 1240px
- Root font size (px per rem)
- 16
- Write lengths in
- rem (follows the reader’s font size)
- Property
- font-size
Example result
| Viewport width (px) | Size (px) | Size (rem) | Where |
|---|---|---|---|
| 240 | 16 | 1 | Held at the size for the minimum viewport |
| 320 | 16 | 1 | Held at the size for the minimum viewport |
| 550 | 18 | 1.125 | Fluid |
| 780 | 20 | 1.25 | Fluid |
| 1,010 | 22 | 1.375 | Fluid |
Slope and intercept are rounded to 4 decimal places; the result differs from the exact line by well under 0.01 px at common widths. rem values assume a root size of 16 px.