Fluid Type and Spacing
AdvancedScaling type and space continuously with clamp() replaces most sizing breakpoints and removes the jumps where a heading changes size mid-drag.
Overview
Breakpoint-based sizing produces layouts that are correct at four widths and awkward between them: a heading at 32px until 768px and then suddenly 48px. Fluid sizing interpolates instead, so the value tracks the viewport smoothly and is right everywhere. clamp() expresses this in one declaration with a floor and a ceiling. The accessibility caveat matters and is widely missed — a preferred value expressed purely in vw stops responding to the user's font size, so a rem term has to be part of the formula.
Fluid Type
clamp() with a mixed rem and vw preferred value.
/* clamp(minimum, preferred, maximum) */
h1 { font-size: clamp(2rem, 1.5rem + 2.5vw, 3.5rem) }
p { font-size: clamp(1rem, 0.95rem + 0.25vw, 1.125rem) }
/* Why the preferred value is a SUM:
clamp(2rem, 5vw, 3.5rem) — pure vw: a user who doubles
their browser font size sees
no change at all
clamp(2rem, 1.5rem + 2.5vw, 3.5rem) — the rem term keeps it
responsive to that setting */
/* Deriving the numbers: to go from 2rem at 320px to 3.5rem at 1280px
slope = (3.5 - 2) / (1280 - 320) * 100vw = 0.156vw per px = 15.6vw... */
/* In practice use a generator (utopia.fyi) rather than the algebra,
and check both ends in the browser. */
/* A fluid scale, defined once as tokens */
:root {
--step--1: clamp(0.83rem, 0.8rem + 0.15vw, 0.94rem);
--step-0: clamp(1rem, 0.96rem + 0.2vw, 1.13rem);
--step-1: clamp(1.2rem, 1.14rem + 0.3vw, 1.41rem);
--step-2: clamp(1.44rem, 1.35rem + 0.45vw, 1.76rem);
}
h2 { font-size: var(--step-2) }Fluid Space
The same technique for padding and gaps, where it matters more than people expect.
:root {
--space-s: clamp(0.75rem, 0.7rem + 0.25vw, 1rem);
--space-m: clamp(1rem, 0.9rem + 0.5vw, 1.5rem);
--space-l: clamp(2rem, 1.6rem + 2vw, 4rem);
--space-xl: clamp(4rem, 3rem + 5vw, 8rem);
}
.section { padding-block: var(--space-xl) }
.card { padding: var(--space-m); gap: var(--space-s) }
/* Generous section padding on a desktop looks absurd on a phone,
and phone padding looks cramped on a desktop. Fluid space fixes
both without a single media query. */
/* The content wrapper — the pattern almost every page needs */
.wrapper {
width: min(100% - 2rem, 72rem);
margin-inline: auto;
}
/* Reads as: full width minus a 1rem gutter each side, capped at
72rem, centred. One declaration replaces width + max-width +
padding + box-sizing. */Intrinsic Layouts
Letting the content decide, so there is nothing left to query.
/* A grid that reflows with no breakpoints at all */
.cards { display: grid; gap: var(--space-m);
grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr)) }
/* A sidebar that becomes a stack when there is not enough room */
.with-sidebar { display: flex; flex-wrap: wrap; gap: var(--space-m) }
.with-sidebar > .side { flex: 1 1 15rem }
.with-sidebar > .main { flex: 999 1 30rem }
/* The huge flex-grow on main means it takes all the space when both
fit; when main cannot reach its 30rem basis, the row wraps and
they stack. No media query, and it responds to the CONTAINER. */
/* Text that never gets too wide to read */
.prose { max-width: 65ch }
/* The principle: describe the constraints and let the browser solve
the layout. Media queries are then for genuine structural changes
— a nav becoming a drawer — rather than for sizing. */Key Points to Remember
- 1clamp() interpolates a value continuously, removing the jumps that breakpoint-based sizing produces
- 2A preferred value in vw alone ignores the user's font-size setting — always include a rem term
- 3Fluid spacing tokens fix both cramped phone padding and absurd desktop padding without media queries
- 4width: min(100% - 2rem, 72rem) with margin-inline: auto is the complete content wrapper in two lines
- 5Intrinsic patterns like auto-fit grids and flex-basis wrapping respond to the container, leaving media queries for real structural changes
Interview Questions
Sign in to ask AriaWhat does clamp() do and why is it useful for typography?
Why is a font-size of clamp(2rem, 5vw, 3rem) an accessibility problem?
How can a sidebar layout collapse to a stack without any media query?
Ask Aria about Fluid Type and Spacing
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.