Fluid Scaling

Type sizes and spacing scale continuously across viewports using clamp() — no breakpoints, no jumps. Pointer detection adapts interaction style to the device. Together, they make responsive design intrinsic.

Why Fluid

Traditional responsive design uses breakpoints — fixed thresholds where layouts snap between states. This creates three problems:

  1. Jarring jumps. A heading that's 2rem at 767px and 3rem at 768px creates a visible pop.
  2. False taxonomy. "Mobile", "tablet", "desktop" are marketing categories, not engineering primitives. A 1024px laptop in portrait mode isn't a tablet.
  3. Combinatorial explosion. Every breakpoint doubles the test matrix. Three breakpoints means eight states to verify.

Fluid scaling replaces this with continuous interpolation. Values ease smoothly from a minimum (at 320px) to a maximum (at 1440px). One rule, infinite states, zero jumps.

Activation

Add the data-fluid attribute to <html>. Remove it to revert to fixed values instantly.

<!-- Default preset --> <html data-fluid> <!-- Named presets --> <html data-fluid="compact"> <html data-fluid="spacious"> <!-- Combine with themes and dark mode --> <html data-theme="ocean" data-fluid data-mode="dark">

Fluid scaling is opt-in so existing sites aren't affected. Once activated, it overrides the static --font-size-* and --size-unit tokens with clamp() values.

What Changes

Typography

Each of the nine --font-size-* tokens gets a clamp() value. Small sizes barely change (xs stays near 0.75rem); large sizes scale dramatically (5xl grows from ~2rem to ~4rem). This creates a tighter ratio at narrow viewports (more uniform hierarchy, easier to scan) and a wider ratio at wide viewports (more dramatic headings, clearer visual weight).

Spacing

All nine --size-* tokens (3xs through 3xl) are derived from --size-unit via calc(). Making --size-unit a clamp() value makes every spacing token fluid automatically — a single override cascades to the entire system.

Content Widths

--content-normal and --measure-normal also scale, expanding reading areas on wider screens while keeping comfortable line lengths on narrow ones.

Presets

AttributeType RatioSpace SwingCharacter
data-fluid="compact" 1.067 → 1.2 ±11% Tight, uniform hierarchy. Good for dense UIs and dashboards.
data-fluid 1.125 → 1.25 ±10% Balanced, general-purpose. Works for most content sites.
data-fluid="spacious" 1.2 → 1.333 ±11% Generous, dramatic headings. Marketing pages and editorial layouts.

Pointer Detection

Pointer detection is always on — no opt-in attribute needed. It uses CSS media queries to adapt interaction style to the device's input capabilities.

/* These rules are always active — no opt-in needed */ /* Touch devices: enforce 44px minimum targets (WCAG 2.5.8) */ @media (pointer: coarse) { button, select, input:not([type="hidden"]) { min-block-size: var(--size-touch-min); /* 2.75rem = 44px */ } } /* No hover capability: disable hover-only motion affordances */ @media (hover: none) { :root { --motion-hover-lift: none; --motion-hover-scale: none; } }

What It Does

@media (pointer: coarse)
Touch and stylus devices get 44px minimum target sizes on buttons, inputs, and selects — enforcing WCAG 2.5.8 target size requirements.
@media (hover: none)
On devices without hover (phones, tablets), hover-only motion effects like lift and scale are disabled. Content remains accessible without hover interactions.

With Themes

data-fluid composes with data-theme. Most themes only customize colors and fonts, so fluid scaling works without any theme-side changes.

The a11y-large-text accessibility theme includes dedicated fluid compound rules — its larger base sizes (1.25rem body, 0.3125rem unit) also scale fluidly when data-fluid is present.

<html data-theme="ocean" data-fluid> <!-- Ocean colors + fluid type/spacing --> <html data-theme="a11y-large-text" data-fluid> <!-- Large text base + fluid scaling = maximum readability -->

Custom Parameters

For full control over ratios and viewport ranges, use the interactive tools:

Both tools produce production-ready clamp() CSS. Paste it into your project stylesheet:

/* Custom fluid preset — paste from the Fluid Sizing tool */ [data-fluid="custom"] { /* Fluid Type Scale */ --font-size-xs: clamp(0.68rem, -0.16vi + 0.82rem, 0.79rem); --font-size-sm: clamp(0.85rem, -0.06vi + 0.90rem, 0.89rem); --font-size-md: clamp(1rem, 0.09vi + 0.98rem, 1.06rem); --font-size-lg: clamp(1.13rem, 0.29vi + 1.07rem, 1.33rem); --font-size-xl: clamp(1.27rem, 0.56vi + 1.15rem, 1.66rem); --font-size-2xl: clamp(1.42rem, 0.93vi + 1.24rem, 2.08rem); --font-size-3xl: clamp(1.60rem, 1.42vi + 1.32rem, 2.59rem); --font-size-4xl: clamp(1.80rem, 2.06vi + 1.39rem, 3.24rem); --font-size-5xl: clamp(2.03rem, 2.89vi + 1.45rem, 4.05rem); /* Fluid Space (via --size-unit — cascades to all --size-* tokens) */ --size-unit: clamp(0.225rem, 0.07vi + 0.21rem, 0.275rem); }

When Not To Use Fluid Scaling