What is Fluid Typography?
Historically, web developers adjusted font sizes by writing media query breakpoints: font-size: 24px on mobile, then font-size: 48px above 768px. The result is a jarring visual jump at the exact breakpoint pixel.
Fluid Typography eliminates those jumps. Using the CSS clamp() function, your text mathematically scales up in perfect sync with the viewport width — no media queries, no sudden shifts, just smooth linear growth between your specified minimum and maximum sizes.
On devices between 768px and 1024px (most tablets and small laptops), traditional breakpoint-based typography is either too small or too large. Fluid typography hits the sweet spot at every width in between.
The clamp() Formula Explained
clamp(MIN, PREFERRED, MAX)
The three arguments are straightforward. MIN and MAX are rem values. The PREFERRED value is where the math happens.
We calculate the slope: (maxSize - minSize) / (maxVp - minVp). Then the y-intercept: minSize - slope × minVp. This gives a linear equation that exactly hits your pixel values at both boundary viewports and interpolates perfectly at every width in between.
The Mathematical Resolution Table in the tool above proves this by showing the exact pixel output at your minimum and maximum viewport — so you can confirm to your designer that the CSS respects their Figma spec precisely.
Why Two Different Scale Ratios?
A typographic scale ratio determines how much each heading step is multiplied from the base. At a ratio of 1.414 (Augmented Fourth), five steps up gives you 16 × 1.414⁵ = ~90px. On a 4K monitor that's beautiful. On a 375px iPhone, a 90px heading takes up your entire screen.
The solution: use a tight ratio for mobile (e.g., 1.125 — Major Second) and a wider ratio for desktop (e.g., 1.250 — Major Third). This generator fluidly interpolates not just the individual sizes, but the ratio itself as the screen expands, so headings grow more dramatically on large screens and stay compact on small ones.
Accessibility: Why REM Units Are Non-Negotiable
Code like clamp(16px, 2vw, 32px) violates WCAG 1.4.4. If a visually impaired user has set their browser default to 24px, your px-based clamp overrides it and forces text back to 16px, ignoring their accessibility setting entirely.
This generator always outputs boundaries in rem units. Because 1rem equals the user's chosen browser font size, your clamp values automatically scale up when a user increases their browser text size setting — achieving WCAG 2.1 Level AA compliance without any extra work.
Figma Integration & Design Token Workflow
Figma does not natively support fluid typography — designers still create separate Mobile, Tablet, and Desktop frames with static pixel values. Here's the handoff workflow that eliminates that friction:
- Designer provides two pixel values per step — one from the 375px mobile frame, one from the 1440px desktop frame.
- Enter those exact values into this generator as your base size and viewport boundaries.
- Check the Resolution Table — it proves the generated
clamp()hits exactly those pixel values at both breakpoints. - Export and paste the CSS Custom Properties into your design token file. Reference with
font-size: var(--step-3)throughout your stylesheet.
Common Mistakes & Edge Cases
- Negative Scaling: Sometimes a secondary label should be smaller on desktop to save space (e.g., captions, fine print). Our algorithm detects when the desktop size is smaller than mobile and automatically flips the clamp boundaries and y-intercept calculations, producing a valid shrinking clamp.
- Container vs Viewport Units: Using
vwin clamp is fine for page-level headings but breaks inside narrow CSS Grid columns on wide screens. The drag visualizer in this tool usescqi(Container Query Inline) units internally for the preview — showing you what a component-scoped clamp would look like. For truly modular components, swapvwforcqiin your exported code. - Setting min and max to the same value: If mobile and desktop sizes are equal, the tool outputs a static
remvalue instead of a clamp — this is correct behaviour and avoids generating a nonsensicalclamp(1rem, 0vw + 1rem, 1rem).