How to fluid typography vs media-query steps
- Step 1Decide where the size lives in the design — Hero and display type benefit most from fluid scaling (big visual range, brand impact at every width). Body text usually wants a narrow fluid range or even a stepped value, because legibility matters more than drama. Component-library tokens often stay stepped so the size is predictable per breakpoint.
- Step 2For the stepped version, write the breakpoint blocks — Pick your widths and declare a size at each: `h1 { font-size: 1.5rem } @media (min-width: 768px) { h1 { font-size: 2rem } } @media (min-width: 1280px) { h1 { font-size: 3rem } }`. Easy to read, but the size is frozen between breakpoints and stops growing past the last one.
- Step 3For the fluid version, set the four inputs here — Enter the smallest size as **Min px**, the largest as **Max px**, and your design's small/large reference widths as **Min vw** / **Max vw**. The generator returns one `clamp()` covering the whole range — no per-breakpoint blocks.
- Step 4Generate and copy the clamp() — Click **Generate**. For a 24→48px hero over 320→1440 you get `clamp(1.500rem, 1.071rem + 2.143vw, 3.000rem)`. Copy it onto your selector. Below 320px it pins at 1.5rem; above 1440px it pins at 3rem.
- Step 5Test the fluid version at extra widths — Because fluid interpolates, the in-between widths matter. Add 480 and 1024 to your usual 320 / 768 / 1280 test list — a step-based design only needs the breakpoints, but a fluid one needs samples across the range to confirm the slope feels right.
- Step 6Consider a hybrid — Keep component sizes stepped for predictability and apply fluid `clamp()` only to a few hero/headline selectors for impact. Generate just those critical expressions here, leaving the rest of your stepped scale untouched. For the full stepped/fluid scale at once, use the [typography-scale-builder](/font-tools/typography-scale-builder), which emits both a static rem scale and a fluid clamp() scale.
Fluid clamp() vs stepped media queries
A practical comparison of the two strategies. 'Fluid' assumes a single clamp() built by this generator; 'Stepped' assumes 2–4 media-query breakpoints.
| Dimension | Fluid (clamp) | Stepped (media queries) |
|---|---|---|
| CSS size | One declaration per size | One base + N media-query overrides |
| Visual quality | Smooth — no jump at any width | Discrete jumps at each breakpoint |
| Behaviour past the last reference width | Pinned at the Max rem ceiling | Frozen at the largest breakpoint's size |
| Testability | Sample several widths (320/480/768/1024/1280) | Test only the breakpoints |
| Browser support | ~95%+ (Chrome 79, FF 75, Safari 13.1) | 100% |
| CLS risk | Low — resolves at layout time | Possible jump at a breakpoint if mismanaged |
Same pattern, both ways
For three common type roles, the stepped CSS versus the exact clamp() this generator emits (root size 16, output to 3 decimals).
| Role | Stepped approach | Fluid clamp() (from this tool) |
|---|---|---|
| Body 16→18 / 320→1440 | 16px; @md 18px | clamp(1.000rem, 0.964rem + 0.179vw, 1.125rem) |
| Heading 24→36 / 320→1440 | 24px; @md 30px; @lg 36px | clamp(1.500rem, 1.286rem + 1.071vw, 2.250rem) |
| Hero 40→96 / 320→1440 | 40px; @md 64px; @xl 96px | clamp(2.500rem, 1.500rem + 5.000vw, 6.000rem) |
What the generator does NOT do
This is a fluid-only generator. It cannot produce stepped CSS, so for the stepped side you write the media queries yourself or use a sibling tool.
| Need | This tool? | Where to go |
|---|---|---|
| One fluid clamp() size | Yes | Right here — four inputs |
| A full fluid scale (xs → 4xl) | No | typography-scale-builder |
| Named CSS variables / tokens | Partial (one --font-size-fluid) | css-variable-generator-font |
| Stepped media-query blocks | No | Write them by hand |
Cookbook
Each recipe shows the stepped version and the fluid version side by side, with the exact clamp() this generator returns so you can compare them in a real stylesheet.
Body text: stepped vs fluid
ExampleBody type wants a narrow range. Stepped jumps from 16 to 18 at a breakpoint; fluid eases between them with a 0.179vw slope so no reader ever notices the change.
Stepped:
p { font-size: 16px; }
@media (min-width: 768px) { p { font-size: 18px; } }
Fluid (Min 16 · Max 18 · 320 → 1440):
p { font-size: clamp(1.000rem, 0.964rem + 0.179vw, 1.125rem); }Section heading: three steps vs one clamp
ExampleA heading often needs three breakpoints stepped. Fluid collapses that to a single line that also covers every width in between.
Stepped:
h2 { font-size: 24px; }
@media (min-width: 768px) { h2 { font-size: 30px; } }
@media (min-width: 1280px) { h2 { font-size: 36px; } }
Fluid (Min 24 · Max 36 · 320 → 1440):
h2 { font-size: clamp(1.500rem, 1.286rem + 1.071vw, 2.250rem); }Hero: the case fluid wins outright
ExampleLarge display type has the widest range and the most awkward breakpoint jumps. Fluid scaling is the clearest win here — and the ceiling stops it ballooning past your Max vw.
Stepped (visible jumps at each step):
h1 { font-size: 40px; }
@media (min-width: 768px) { h1 { font-size: 64px; } }
@media (min-width: 1440px) { h1 { font-size: 96px; } }
Fluid (Min 40 · Max 96 · 320 → 1440):
h1 { font-size: clamp(2.500rem, 1.500rem + 5.000vw, 6.000rem); }Hybrid: stepped components, fluid hero
ExampleKeep the predictable stepped sizes for buttons, labels and cards; reserve fluid clamp() for the one or two selectors where smooth scaling reads best.
/* Components stay stepped (predictable) */
.btn { font-size: 0.875rem; }
.label { font-size: 0.75rem; }
/* Hero goes fluid (generated here) */
.hero-title {
font-size: clamp(2.500rem, 1.500rem + 5.000vw, 6.000rem);
}Match a stepped design's endpoints exactly
ExampleIf you already have a stepped design with 16px small and 24px large at 320 and 1280, set those four numbers and the fluid version will hit the same endpoints — only the in-between widths change.
Existing stepped endpoints: 16px @ 320, 24px @ 1280 Fluid (Min 16 · Max 24 · 320 → 1280): font-size: clamp(1.000rem, 0.833rem + 0.833vw, 1.500rem); At 320px → exactly 16px. At 1280px → exactly 24px. The difference from stepped is only between those widths.
Edge cases and what actually happens
Every row below was probed against the live API. Some documented requirements (alphabetical axis order, numerical tuple order) are not actually enforced in practice — useful to know if you've been blaming the wrong thing for a 400.
Fluid over-grows on ultrawide screens
Solved by the ceilingA common fear with vw-based sizing is text becoming gigantic on a 4K monitor. clamp()'s Max rem bound prevents this: past your Max vw the size is pinned. The generator always emits that ceiling, so set Max vw to where you want growth to stop (the field allows up to 2400) and the text will not keep scaling beyond it.
Stepped text jumps mid-resize
Inherent to steppedWith media queries, dragging the window across a breakpoint produces an instant size change. That is by design for stepped typography and is sometimes acceptable, but it is the discontinuity fluid clamp() exists to remove. If the jump is jarring, switch that selector to a clamp() generated here.
Fluid value drifts from your design comps
Expected — test in betweenDesigners usually comp at fixed widths (320, 768, 1280). A fluid clamp() will match your typed endpoints exactly but produce its own size at every width in between — which may not match a comp that was only drawn at breakpoints. Sample 480 and 1024 against the comps to confirm the slope feels right.
Old browser ignores clamp()
Rare — provide a fallbackAn engine that does not understand clamp() drops the whole declaration and uses whatever font-size is otherwise in effect (inherited or default). For a tiny legacy audience, precede the clamp() line with a plain font-size: 1rem; fallback so those browsers still get a sensible size. Modern coverage is ~95%+, so this is rarely necessary in 2026.
This tool cannot emit the stepped CSS
By designThe generator only produces clamp(). It will not write media-query blocks for you — there is no breakpoint field. Author the stepped side by hand, or use the typography-scale-builder, whose output includes a static rem scale alongside the fluid clamp() scale.
Max vw not greater than Min vw on the fluid side
Error — rejectedWhen you build the fluid version, Max vw must exceed Min vw or the tool throws Max viewport must be greater than min viewport. Stepped CSS has no equivalent constraint because you just list independent breakpoint values — this is purely a fluid-generation guard.
Hybrid: forgetting which selectors are fluid
Process risk, not a bugMixing stepped and fluid is powerful but can confuse maintainers who do not know which selectors interpolate. Keep the fluid ones grouped and commented (the generator's output already includes a descriptive comment header you can paste alongside the rule).
Body text fluid range set too wide
Avoidable — keep it narrowBody copy reads best in a tight range (e.g. 16→18 or 16→20). A wide fluid body range (16→28) makes paragraphs noticeably bigger on desktop, which can hurt line-length and rhythm. The generator allows it, but for body text keep Max px close to Min px; save the dramatic ranges for headings.
Root size mismatch makes fluid not match stepped px
By design — root fixed at 16The fluid output assumes a 16px root (Min px ÷ 16 = rem floor). If your stepped CSS uses px and your html root is not 16, the fluid rem values will not visually equal the stepped px. Align your root to 16, or convert the stepped px to rem before comparing.
Frequently asked questions
Is fluid always better than stepped?
No. Fluid reads more smoothly and uses less CSS, but stepped is easier to spec, test, and reason about, and has 100% support. Use fluid for hero/display type and narrow-range body; keep stepped where predictability matters, such as component-library tokens. A hybrid is common.
Can this tool generate the stepped media queries too?
No — it only generates clamp(). There is no breakpoint field. Write the media queries yourself, or use the typography-scale-builder, whose output includes both a static rem scale (which you can wrap in media queries) and a fluid clamp() scale.
Will the fluid version match my design's breakpoint sizes?
It will match exactly at the two viewport widths you enter (Min vw and Max vw). In between, it interpolates linearly, so the size at, say, 768px is computed by the slope, not pulled from a comp. Test the in-between widths against your designs.
Does fluid typography hurt CLS more than stepped?
No — usually the opposite. clamp() resolves at layout time before CLS measurement, so the size is settled before paint. Stepped sizing can introduce a jump exactly at a breakpoint width. Neither is a CLS problem when applied consistently.
What is the browser support difference?
Media queries are 100%. clamp() is ~95%+ (Chrome 79, Firefox 75, Safari 13.1, all 2019–2020). Browsers without clamp() drop the declaration and use the otherwise-effective font-size, so add a plain fallback line if you must support very old engines.
How many breakpoints does a stepped approach need?
Typically 2–4 (e.g. base, tablet, desktop, and sometimes ultrawide). Fluid collapses all of those into one clamp(). If you find yourself adding a fifth or sixth breakpoint to smooth a jump, that is the signal to switch that size to fluid.
Can I do a hybrid where most sizes are stepped and one is fluid?
Yes, and it is a good pattern. Keep component sizes stepped for predictability and generate fluid clamp() expressions here only for the hero/headline selectors that benefit from smooth scaling. The two strategies coexist fine in one stylesheet.
Why does the fluid size stop growing on big screens?
Because clamp()'s Max rem bound is a hard ceiling — past your Max vw the size is pinned. The generator always includes that bound. This is the main reason fluid is safe on ultrawide displays where naive vw sizing would explode.
What extra widths should I test for fluid?
Beyond your usual 320 / 768 / 1280, add 480 and 1024. Fluid interpolation means in-between widths produce their own sizes, so those samples confirm the slope feels right rather than just checking the endpoints.
Is the clamp() output in rem or px?
The Min and Max bounds are rem (Min px ÷ 16, Max px ÷ 16); the middle preferred term combines a rem intercept with a vw slope. rem bounds respect the user's browser font-size preference, which px would override — better for accessibility.
Can I match a stepped design exactly, then go fluid later?
Yes. Enter your stepped design's smallest and largest sizes and the widths they occur at; the fluid clamp() will hit the same endpoints. Only the in-between behaviour changes, so you can swap from stepped to fluid with confidence the extremes are unchanged.
Does the tool upload anything to compare fonts?
No. It is a generator with no file input — it only does clamp() math from four numbers. It does not read or compare font files; for that, see the font-metrics-analyzer or other analysis tools.
Where do I get a complete fluid scale instead of one size?
The typography-scale-builder. Give it a base size and a modular ratio and it emits a clamp() per step (xs → 4xl) plus a static rem scale. This clamp tool is intentionally one-size-at-a-time.
Privacy first
Every JAD Font tool runs entirely in your browser using opentype.js and the wawoff2 WASM Brotli encoder. Your fonts never leave your device — verified by zero outbound network requests during processing.