Three tools for sizing things in CSS:
- Convert units: a length in px, rem, em, pt, %, vw, vh, vmin, vmax, in, cm, mm or pc, shown in every other unit at once. The context is yours to set: root font size (what rem means), parent font size (what em means), what 100% refers to, and the viewport size (what vw and vh mean).
- Fluid clamp(): give a size at a small viewport and a size at a large one, and get the clamp() value that grows linearly between them, the formula behind it, the size at common widths, a live preview with a width slider, and a check that zooming still works.
- Type and spacing scale: a modular scale (base × ratio to the power of the step) and a spacing scale, static or fluid, written as CSS custom properties, a Tailwind v4 @theme block or a Tailwind v3 config.
How the units relate
Absolute CSS units are fixed: 1in = 96px, 1pt = 1/72 in = 1.333px, 1pc = 12pt = 16px, 1cm = 37.8px. They are "CSS pixels", not physical device pixels. Relative units depend on the context: rem is the root font size (16px unless the visitor or the page changes it), em is the font size of the parent element (or of the element itself for properties other than font-size), % is relative to something that depends on the property, and vw / vh are 1% of the viewport width and height. 24px is 1.5rem at a 16px root, 18pt, and 1.6667vw on a 1440px-wide window.
Why it matters: a visitor who sets their browser's default font size to 20px expects text to grow. Sizes in rem follow that setting; sizes in px ignore it (browser zoom still scales both).
For a size that goes from S₁ at viewport width W₁ to S₂ at W₂:
- slope = (S₂ − S₁) / (W₂ − W₁)
- intercept = S₁ − slope × W₁
- font-size: clamp(S₁, intercept + slope × 100vw, S₂)
For 16px at 320px to 24px at 1280px: slope = 8 / 960 = 0.008333, so the vw part is 0.8333vw; intercept = 16 − 320 × 0.008333 = 13.333px = 0.8333rem. The result is clamp(1rem, 0.8333rem + 0.8333vw, 1.5rem): 16px up to 320px wide, 20px at 800px, 24px from 1280px on. The tool writes sizes and the intercept in rem so the value keeps following the root font size, and shows the linear formula so you can check it.
Accessibility: fluid type and zoom
Browser zoom enlarges rem and px, but not the vw part: at 200% zoom the viewport is half as wide in CSS pixels, so the vw part shrinks. If most of a size comes from vw, zooming barely changes it, which can fail WCAG 1.4.4 (text resizable to 200%). Two habits avoid that: keep a solid rem part in the preferred value (the tool always does), and keep the range modest. A rule of thumb from published analyses of fluid type is that the largest size should be no more than 2.5 times the smallest; the tool warns when a pair exceeds it. Test with real zoom anyway.
Type and spacing scales
A modular scale multiplies a base size by a ratio for each step: with 16px and a major third (1.25), the steps are 12.8, 16, 20, 25, 31.25 and 39.06px. A fluid scale uses a smaller base and ratio on phones and larger ones on wide screens, and turns every step into its own clamp(), so headings grow more than body text. The spacing scale multiplies a base space (0.25× to 6×) the same way. Copy the CSS variables (--step-0, --space-m…) or the Tailwind version. For colour and layout values, see the CSS gradient generator and grid and flexbox generator; the reasoning behind rem and clamp() is in rem vs px vs clamp() for fluid type.