Build harmonically proportioned type scales using Major Third, Perfect Fourth, and Golden Ratio. Implement them as CSS custom property token systems for consistent typographic hierarchy.
A modular type scale applies a single multiplication ratio to a base size to generate every font size in the system. The result is a set of sizes that are mathematically harmonious — they feel related because they are related. This is why a site using a consistent scale feels visually coherent while one with arbitrary font sizes feels chaotic, even if the viewer cannot articulate why. This lesson builds a complete token-based type scale system from first principles.
A modular scale starts with a base size (typically 1rem / 16px) and multiplies or divides by a ratio to generate each step up or down. With a Perfect Fourth ratio (1.333): base = 1rem, one step up = 1.333rem, two steps up = 1.777rem, three steps up = 2.369rem. Dividing: one step down = 0.75rem, two steps down = 0.563rem. The same ratio that governs musical intervals governs visual harmony — hence 'Perfect Fourth'. Common ratios and their use cases: Minor Second (1.067) for very tight UI scales where size differences must be subtle. Major Second (1.125) for dense data interfaces. Major Third (1.25) for balanced UI typography. Perfect Fourth (1.333) for editorial and blog content. Perfect Fifth (1.5) for bold marketing. Golden Ratio (1.618) for dramatic display headlines. Augmented Fourth (1.414) — the square root of 2 — is another popular choice for its geometric elegance. There is no universally correct ratio; choose based on the visual weight contrast you need between heading levels.
For a Perfect Fourth scale (ratio = 1.333) with 1rem base:
Step -2: 1 / 1.333^2 = 0.563rem (9px) — very small
Step -1: 1 / 1.333 = 0.75rem (12px) — small
Step 0: 1rem = 1rem (16px) — base
Step +1: 1 × 1.333 = 1.333rem (21.3px) — h4
Step +2: 1 × 1.333^2 = 1.777rem (28.4px) — h3
Step +3: 1 × 1.333^3 = 2.369rem (37.9px) — h2
Step +4: 1 × 1.333^4 = 3.157rem (50.5px) — h1
Step +5: 1 × 1.333^5 = 4.209rem (67.3px) — display
1/* Perfect Fourth scale tokens */
2:root {
3 --ratio: 1.333; /* Perfect Fourth */
4 --base: 1rem;
5
6 /* Calculated: base * ratio^n */
7 --step--2: 0.563rem;
8 --step--1: 0.75rem;
9 --step-0: 1rem;
10 --step-1: 1.333rem;
11 --step-2: 1.777rem;
12 --step-3: 2.369rem;
13 --step-4: 3.157rem;
14 --step-5: 4.209rem;
15}
16
17body { font-size: var(--step-0); }
18small { font-size: var(--step--1); }
19h4 { font-size: var(--step-1); }
20h3 { font-size: var(--step-2); }
21h2 { font-size: var(--step-3); }
22h1 { font-size: var(--step-4); }
23.display { font-size: var(--step-5); }The visual weight jump between heading levels depends entirely on the ratio. A 1.067 ratio (Minor Second) creates barely perceptible size steps — the hierarchy feels flat and subtle. A 1.618 ratio (Golden Ratio) creates dramatic jumps that feel striking in display contexts but overwhelming in body text. Rule of thumb: dense UI components (data tables, admin panels, dashboards) use a tight ratio (1.067–1.125) because many heading levels appear simultaneously and a dramatic scale would feel visually noisy. Editorial and blog content use a moderate ratio (1.25–1.333) — clear hierarchy between heading levels without excessive visual jumps. Marketing and landing pages use a bold ratio (1.414–1.618) — the dramatic contrast between body text and display headings creates visual impact.
1/* Tight scale for dense UI (Major Second: 1.125) */
2:root {
3 --ui-text-sm: 0.889rem; /* 14.2px */
4 --ui-text-base: 1rem; /* 16px */
5 --ui-text-md: 1.125rem; /* 18px */
6 --ui-text-lg: 1.266rem; /* 20.3px */
7 --ui-text-xl: 1.424rem; /* 22.8px */
8}
9
10/* Bold scale for marketing (Perfect Fifth: 1.5) */
11:root {
12 --mkt-text-sm: 0.667rem; /* 10.7px */
13 --mkt-text-base: 1rem; /* 16px */
14 --mkt-text-h3: 1.5rem; /* 24px */
15 --mkt-text-h2: 2.25rem; /* 36px */
16 --mkt-text-h1: 3.375rem; /* 54px */
17 --mkt-text-display: 5.063rem; /* 81px */
18}A static modular scale has fixed sizes; a fluid scale built only with vw units has no harmonic ratios. Combining the two gives you harmonically proportioned sizes that also scale fluidly across viewport widths. The approach: calculate the MIN using a tighter ratio (1.25) for mobile sizes, calculate the MAX using a bolder ratio (1.333) for desktop sizes, and use clamp() to span the range. This creates a fluid scale where both endpoints are harmonically sound and the scaling is continuous.
1/* Fluid modular scale: Major Third at mobile, Perfect Fourth at desktop */
2:root {
3 /* step-1: 1.25rem mobile → 1.333rem desktop */
4 --text-h4: clamp(1.25rem, 1.195rem + 0.27vw, 1.333rem);
5
6 /* step-2: 1.563rem mobile → 1.777rem desktop */
7 --text-h3: clamp(1.563rem, 1.44rem + 0.61vw, 1.777rem);
8
9 /* step-3: 1.953rem mobile → 2.369rem desktop */
10 --text-h2: clamp(1.953rem, 1.77rem + 0.91vw, 2.369rem);
11
12 /* step-4: 2.441rem mobile → 3.157rem desktop */
13 --text-h1: clamp(2.441rem, 2.126rem + 1.57vw, 3.157rem);
14
15 /* step-5: 3.052rem mobile → 4.209rem desktop */
16 --text-display: clamp(3.052rem, 2.548rem + 2.52vw, 4.209rem);
17}Custom property tokens only work if you apply them consistently to semantic HTML. The scale tokens should be applied at the element level, not with utility classes that require memorising class names. Overrides should use the same token system, not arbitrary values. This ensures every font size in the system is a scale step — never a one-off number like font-size: 17px inserted because something needed to 'just be a bit bigger'. Discipline in applying the scale is what creates visual harmony.
1/* Apply scale to semantic HTML elements */
2body {
3 font-size: var(--step-0);
4 line-height: 1.6;
5 font-family: var(--font-body);
6}
7
8h1, h2, h3, h4, h5, h6 {
9 font-family: var(--font-heading);
10 line-height: 1.2;
11 font-weight: 700;
12 /* Spacing: give headings room to breathe */
13 margin-block-start: 2em;
14 margin-block-end: 0.5em;
15}
16
17h1 { font-size: var(--step-4); }
18h2 { font-size: var(--step-3); }
19h3 { font-size: var(--step-2); }
20h4 { font-size: var(--step-1); }
21h5, h6 { font-size: var(--step-0); font-weight: 600; }
22
23.display {
24 font-size: var(--step-5);
25 line-height: 1.05;
26 letter-spacing: -0.02em; /* Tight tracking for large display text */
27}Perfect Fourth type scale as CSS tokens applied to a full article layout.
Next lesson covers line height, letter spacing, and optimal measure — the three properties that determine whether a typeface is actually readable in body text.
Your progress is saved in this browser, on this device only.