About this snippet

A short article set in six sizes, from a display heading down to a caption. Resize the window and every size slides between its phone value and its desktop value without a single breakpoint, so the text never jumps at an arbitrary width.

Each step is a custom property built with clamp. The first argument is the smallest size, the last is the largest, and the middle one is a preferred size that mixes a rem base with a slice of the viewport width. The rem part is what keeps the scale honest. A pure vw value would ignore the visitor's font size setting, while the mix keeps the text growing with the viewport and still respecting browser zoom.

The properties are defined once on the root, so adjusting the whole hierarchy means editing six lines rather than hunting through media queries.

Size
2.1 KB
Uses
HTML, CSS
Loads
Nothing external
Views
30
<article class="page">
  <p class="caption">Type scale</p>
  <h1>Set your type once and let the viewport do the rest</h1>
  <p class="lead">Six sizes, each defined with clamp, that move between a phone value and a desktop value as the layout changes width.</p>
  <h2>Why a fluid scale beats breakpoints</h2>
  <p>A breakpoint changes the size all at once, so a heading that fits at 767 pixels can suddenly wrap at 768. A fluid scale changes by fractions of a pixel as the viewport moves, and the text simply settles wherever the screen happens to be.</p>
  <h3>Keeping it readable</h3>
  <p>Mixing a rem base into the preferred value keeps the scale tied to the reader's own font size setting, and capping the measure at sixty characters stops lines running too long on wide screens.</p>
  <p class="caption">Resize the preview to watch the sizes change.</p>
</article>
:root {
  --step-0: clamp(1rem, 0.93rem + 0.35vw, 1.1875rem);
  --step-1: clamp(1.125rem, 1rem + 0.6vw, 1.5rem);
  --step-2: clamp(1.375rem, 1.15rem + 1.1vw, 2rem);
  --step-3: clamp(1.75rem, 1.35rem + 2vw, 2.875rem);
  --step-4: clamp(2.25rem, 1.5rem + 3.6vw, 4.25rem);
  --step--1: clamp(0.8125rem, 0.78rem + 0.15vw, 0.9375rem);
}

*, *::before, *::after {
  box-sizing: border-box;
}

body {
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  margin: 0;
  background: #fafaf9;
  color: #1c1917;
  padding: clamp(24px, 6vw, 72px) 20px;
}

.page {
  max-width: 60ch;
  margin: 0 auto;
}

.caption {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #78716c;
  margin: 0 0 16px;
}

h1 {
  font-size: var(--step-4);
  line-height: 1.05;
  letter-spacing: -0.025em;
  margin: 0 0 20px;
}

.lead {
  font-size: var(--step-1);
  line-height: 1.5;
  color: #44403c;
  margin: 0 0 40px;
}

h2 {
  font-size: var(--step-3);
  line-height: 1.15;
  letter-spacing: -0.02em;
  margin: 0 0 14px;
}

h3 {
  font-size: var(--step-2);
  line-height: 1.25;
  letter-spacing: -0.01em;
  margin: 32px 0 12px;
}

p {
  font-size: var(--step-0);
  line-height: 1.65;
  margin: 0 0 18px;
}

.page .caption:last-child {
  margin-top: 36px;
}
Esc
↑↓ moveEnter select

Start from a template

Open an .html file, or HTML, CSS, JS, Markdown, Less or TypeScript files. You can also drop them here. Styles and scripts go into their panes.

Share

Source

Keyboard shortcuts

Save