Home / Snippets / Typography /

Fluid typography

clamp() — smooth, continuous scaling between min and max.

The Future of CSS
Performance-first design

Resize the window — both headings and body text scale smoothly without a single media query.

Type scale (resize to see fluid scaling):

xssmbaselgxl
Widely supported
typography

Quick implementation

/* clamp(min, preferred, max) */
/* preferred = a vw-based value that gives the "slope" */

h1 {
  font-size: clamp(1.75rem, 5vw, 3rem);
  line-height: 1.1;
  letter-spacing: -0.03em;
}
h2 {
  font-size: clamp(1.25rem, 3vw, 2rem);
  line-height: 1.2;
}
p {
  /* Preferred: 1.5vw + a fixed offset for a gentler slope */
  font-size: clamp(0.9375rem, 0.875rem + 0.3125vw, 1.0625rem);
  line-height: 1.7;
}
/* Full fluid scale (CSS custom properties) */
:root {
  --text-xs:   clamp(0.75rem,  0.7rem  + 0.25vw,  0.875rem);
  --text-sm:   clamp(0.875rem, 0.8rem  + 0.375vw, 1rem);
  --text-base: clamp(1rem,     0.95rem + 0.25vw,   1.125rem);
  --text-lg:   clamp(1.125rem, 1rem    + 0.625vw,  1.375rem);
  --text-xl:   clamp(1.25rem,  1rem    + 1.25vw,   1.75rem);
  --text-2xl:  clamp(1.5rem,   1rem    + 2.5vw,    3rem);
}

Prompt this to your LLM

Includes a full type-scale system, slope formula, and design token variant.

You are a senior frontend engineer.

Goal: Create a complete fluid typography system using CSS clamp() — no media queries.

Technical constraints:
- Use clamp(min, preferred, max) for every font-size level.
- The preferred value should create a slope: either a bare vw value (e.g. 5vw) or a mixed calculation (e.g. 1rem + 1.5vw) for a gentler slope.
- Minimum: never smaller than readable (≥0.75rem for small text, ≥1rem for body).
- Maximum: capped so headings don't become enormous on wide monitors.
- Define the scale as CSS custom properties (--text-xs through --text-2xl) so they can be used across the design system.

Design system variant:
A) CSS custom properties only — define the scale in :root { }
B) Tailwind-style: generate a tailwind.config.js fontSize section that maps the same scale using clamp().

Edge cases:
- Note that clamp() respects browser font-size zoom because the vw part scales with viewport, not with root font size. However, for pure accessibility, also consider using rem-only clamp where the middle value is font-size + vw: clamp(1rem, calc(1rem + 1vw), 2rem).
- Mention the fluid-type.app or similar tools for generating precise clamp() values.

Return the full CSS custom property scale + usage examples for h1, h2, h3, p, and small.

Why this matters in 2026

Fluid type replaces the classic breakpoint pattern — where you set one font size at mobile and a different one at desktop — with a continuous slope. The result looks right at every width, not just the two you tested. One clamp() per type level, and you're done.

In 2026, it's also the foundation of "intrinsic" design: sizing that adapts to the available space rather than the device category. Combined with container queries and subgrid, it produces layouts that are truly responsive without a pile of media queries.

The logic

clamp(min, preferred, max): the browser uses the preferred value (often a vw unit or a calc() expression) clamped between min and max. The slope is how fast the size grows as the viewport widens. A gentle slope uses 1rem + 1vw; a steeper one uses 5vw directly.

The formula for a mathematically precise slope (from a min viewport to a max viewport) is: clamp(minSize, minSize + (maxSize - minSize) * ((100vw - minVw) / (maxVw - minVw)), maxSize). Tools like fluid-type.app will generate this for you.

Accessibility & performance

Don't set the minimum below 1rem for body text — 16px is the accessible default. Using a combination of rem and vw in the middle value (1rem + 0.5vw) respects user font-size preferences in the browser: the rem part scales up when the user increases base font size.

Prefer clamp(1rem, 0.9rem + 0.5vw, 1.125rem) for body — the rem baseline means user zoom still works.