Tool

Type scale.

A modular type scale built from a base size and a musical ratio. Live preview, dual line-heights for heads vs body, and exports as CSS variables, SCSS map, or Tailwind theme. The hierarchy that makes a design system feel coherent.

Base
16px
Ratio
1.250
Steps
9
Span
0.640rem–3.815rem

Unit
Ratio presets
Live preview
-2 0.640rem

The quick brown fox jumps over the lazy dog

-1 0.800rem

The quick brown fox jumps over the lazy dog

base 1.000rem

The quick brown fox jumps over the lazy dog

sm 1.250rem

The quick brown fox jumps over the lazy dog

md 1.563rem

The quick brown fox jumps over the lazy dog

lg 1.953rem

The quick brown fox jumps over the lazy dog

xl 2.441rem

The quick brown fox jumps over the lazy dog

2xl 3.052rem

The quick brown fox jumps over the lazy dog

3xl 3.815rem

The quick brown fox jumps over the lazy dog

CSS utility classes
.text--2 { font-size: 0.640rem; line-height: 0.960rem; }
.text--1 { font-size: 0.800rem; line-height: 1.200rem; }
.text-base { font-size: 1.000rem; line-height: 1.500rem; }
.text-sm { font-size: 1.250rem; line-height: 1.875rem; }
.text-md { font-size: 1.563rem; line-height: 1.875rem; }
.text-lg { font-size: 1.953rem; line-height: 2.344rem; }
.text-xl { font-size: 2.441rem; line-height: 2.930rem; }
.text-2xl { font-size: 3.052rem; line-height: 3.662rem; }
.text-3xl { font-size: 3.815rem; line-height: 4.578rem; }
CSS custom properties
:root {
  --font-size--2: 0.640rem;
  --font-size--1: 0.800rem;
  --font-size-base: 1.000rem;
  --font-size-sm: 1.250rem;
  --font-size-md: 1.563rem;
  --font-size-lg: 1.953rem;
  --font-size-xl: 2.441rem;
  --font-size-2xl: 3.052rem;
  --font-size-3xl: 3.815rem;
  --line-height--2: 0.960rem;
  --line-height--1: 1.200rem;
  --line-height-base: 1.500rem;
  --line-height-sm: 1.875rem;
  --line-height-md: 1.875rem;
  --line-height-lg: 2.344rem;
  --line-height-xl: 2.930rem;
  --line-height-2xl: 3.662rem;
  --line-height-3xl: 4.578rem;
}
SCSS map
$type-scale: (
  '-2': (size: 0.640rem, line-height: 0.960rem),
  '-1': (size: 0.800rem, line-height: 1.200rem),
  'base': (size: 1.000rem, line-height: 1.500rem),
  'sm': (size: 1.250rem, line-height: 1.875rem),
  'md': (size: 1.563rem, line-height: 1.875rem),
  'lg': (size: 1.953rem, line-height: 2.344rem),
  'xl': (size: 2.441rem, line-height: 2.930rem),
  '2xl': (size: 3.052rem, line-height: 3.662rem),
  '3xl': (size: 3.815rem, line-height: 4.578rem),
);
Tailwind config
module.exports = {
  theme: {
    extend: {
      fontSize: {
        '-2': ['0.640rem', { lineHeight: '0.960rem' }],
        '-1': ['0.800rem', { lineHeight: '1.200rem' }],
        'base': ['1.000rem', { lineHeight: '1.500rem' }],
        'sm': ['1.250rem', { lineHeight: '1.875rem' }],
        'md': ['1.563rem', { lineHeight: '1.875rem' }],
        'lg': ['1.953rem', { lineHeight: '2.344rem' }],
        'xl': ['2.441rem', { lineHeight: '2.930rem' }],
        '2xl': ['3.052rem', { lineHeight: '3.662rem' }],
        '3xl': ['3.815rem', { lineHeight: '4.578rem' }],
      }
    }
  }
}

A geometric sequence is visibly different.

Type sizes picked at random — 12, 14, 18, 24, 32, 48 — produce a hierarchy that feels off. The eye notices that the gap from 12 to 14 is two pixels and the gap from 32 to 48 is sixteen, but the proportional change is wildly different (16% vs 50%). A geometric progression solves this by making each step proportionally identical: 12, 14.4, 17.3, 20.7, 24.9, 29.9, 35.8 — every number is 1.2× the previous. The eye reads consistent intervals as deliberate; inconsistent intervals as accident.

Robert Bringhurst, in The Elements of Typographic Style (1992), traces this idea back to the typographic ladders printers used for centuries — fixed multiples of a base size that produced harmonious hierarchies without thinking. Tim Brown formalised it for the web in 2010 with his "More Meaningful Typography" essay on A List Apart, then in 2011 launched modularscale.com, the original tool that made musical ratios approachable for screen designers. The vocabulary the web uses today — minor third, perfect fifth, golden ratio — comes directly from his article.

The musical analogy is less arbitrary than it sounds. Pythagoras observed that strings of length ratios 2:1, 3:2, and 4:3 produce the most consonant intervals (octave, perfect fifth, perfect fourth). The same simple ratios feel right on the page because the eye, like the ear, prefers ratios that fit small whole numbers. The minor third (6:5 = 1.2), major third (5:4 = 1.25), perfect fourth (4:3 = 1.333), and perfect fifth (3:2 = 1.5) are all small-integer ratios. The golden ratio (φ ≈ 1.618) is famously the most aesthetically pleasing irrational ratio — its appearance in nature and classical art is part myth and part fact, but it does produce a striking type scale.

A geometric scale also composes. If you double the base, every size doubles. If you nest a smaller component (say, a card inside a page), you can halve the ratio's exponent and produce a sub-hierarchy that's still proportional to the parent. That's why design systems built on modular scales survive redesigns: when the brand moves to a new base font, every size moves in concert.

Each ratio has a personality.

The minor second (1.067) is barely visible at small sizes — the difference between 16 and 17 pixels is one pixel — but compounds dramatically. Eight steps from 16px gives you about 27px. Best for very dense interfaces where the hierarchy is communicated by weight, color, and position more than size.

The major second (1.125) is the most popular ratio in shipped UI work. Tailwind's default scale, GitHub's Primer, and most B2B SaaS dashboards live near here. Each step is visibly different but never dramatic; the result feels professional, low-key, and information-dense.

The minor third (1.2) and major third (1.25) are the sweet spot for most content sites. Hierarchy reads clearly, headlines feel important without overpowering, body copy stays comfortable. If you're not sure where to start, this tool's default of 1.25 is a safe choice. Material Design 3, Apple's Human Interface Guidelines, and most editorial sites converge on something near here.

The perfect fourth (1.333) crosses into editorial territory. Each step is dramatic enough that headlines feel like headlines and small text feels small; the gap between 16 and 21 pixels is unmistakable. Used by The New York Times, Medium, and most long-form publications. The risk is a "shouting" feel if every level steps up — typically you skip levels (use base, lg, 3xl, not every adjacent step).

The augmented fourth (1.414, also known as the diabolus in musica) is the square root of 2 — the ratio between A4 paper sides. Mathematically elegant, visually slightly off-balance, which can be the right kind of tension for art-directed sites. Less common in shipped systems but distinctive.

The perfect fifth (1.5) and golden ratio (1.618) are dramatic. Scales feel luxurious; headlines feel like declarations. Excellent for hero pages, landing pages, brand sites. Risky for dense layouts — the lg size is already 1.5× the base, the 2xl is 3.4×, and at 6xl you're past 11× the base. Reserve for marketing or use sparingly within a smaller working scale.

RatioNameBest forCaution
1.067Minor Seconddata-dense UIweak hierarchy at small sizes
1.125Major SecondSaaS dashboards, admincan feel timid for hero copy
1.200Minor Thirdgeneral content sites
1.250Major Thirdmost editorial / blog UIs
1.333Perfect Fourthlong-form publicationscan read "shouty" if overused
1.414Augmented Fourthart-directed sitesuncommon; less familiar
1.500Perfect Fifthmarketing / brand pagestoo dramatic for dashboards
1.618Golden Ratioluxury / classical feelcompounds fast; cap at lg/xl

Units shape accessibility.

The unit you ship affects how the type scale interacts with user preferences. px is fixed: a user who has bumped their browser font-size to 20px (because their eyesight requires it) will still see 16px body text on your site. This is the single most common accessibility failure in web design — sites that ship px-sized type override the user's choice and leave them squinting.

rem is sized relative to the root font-size, which by default is the user's chosen value. Setting body type to 1rem means it scales with the user's preference automatically. The scale this tool generates in rem units divides every pixel value by 16 (the standard root default) — a 24px size becomes 1.5rem, a 12px size becomes 0.75rem. If the user's browser is set to 20px, every size on your site grows proportionally.

em is sized relative to the parent element's font-size, which sounds similar to rem but compounds. A list inside a list inside a list, each at font-size: 0.9em, ends up at 0.729em of the outermost. For a type scale, this is almost always the wrong primitive — use rem for global sizing and reserve em for local component-internal scaling (a button's padding sized to its own font, for instance).

Modern browsers also support clamp() for fluid typography: font-size: clamp(1rem, 1rem + 0.5vw, 1.5rem) scales between two values based on viewport width. This lets a single declaration produce responsive sizes without media queries. The trade-off is that clamp values are harder to express in a token system; most design systems pick discrete sizes per breakpoint instead. For marketing pages with hero copy, fluid typography is striking; for utility pages, discrete is calmer.

Default to rem

Use rem for type sizes, padding, margins, and any layout dimensions that should respect user preferences. Use px only for borders, dividers, hairlines, and other small fixed details that shouldn't scale. The unit-converter tool nearby can show you exact conversions.

Body and head need different rules.

A type scale is half the picture; line-height is the other half. The same 16px body type at 1.2 line-height feels cramped and headache-inducing; at 1.6 line-height it feels open and readable. The difference between a magazine article and a dashboard label is largely a line-height choice, not a size choice.

The conventional ranges are well-established. Body text wants 1.4–1.6 line-height for comfortable reading, with 1.5 being the standard textbook value. Long-form articles often go higher (1.6–1.8) for relaxation; dense reference material can go lower (1.4) for density. Headlines want 1.1–1.3 — tight enough that the headline reads as one visual unit, not as several lines. Display sizes (the largest 3xl-6xl tokens in this scale) often go even tighter, sometimes below 1.0 for very large hero copy where leading would feel like wasted vertical space.

This tool applies a heuristic: anything above 1.4× the base size gets the heading line-height; everything else gets the body line-height. You can tune both sliders independently. The crossover threshold isn't magical — it's roughly the size at which a single line dominates the eye's attention enough that wider line spacing reads as awkward gap rather than comfortable rhythm.

A second consideration: line-height in CSS can be specified unitless (line-height: 1.5) or with units (line-height: 24px). Unitless is dramatically better for inheritance — when a child element changes its font-size, an inherited unitless line-height multiplies cleanly; an inherited unit-bearing line-height stays fixed and produces wrong-feeling spacing. The tool emits both forms in its outputs; for general-purpose stylesheets, unitless is the right default.

From breakpoints to continuous scaling.

For years the standard pattern was discrete responsive sizes: define a base scale at mobile, override every size at the tablet breakpoint, override again at desktop. The CSS swelled (three or four declarations per token times every component), and the boundary jumps felt abrupt — the headline that was 32px at 767px width became 40px at 768px. Mike Riethmuller's "Precise control over responsive typography" (2015) introduced the formula that made fluid typography practical, and Utopia (utopia.fyi, 2020) packaged it into a generative tool.

The CSS clamp(min, preferred, max) function does the work in one declaration. clamp(1rem, 0.875rem + 0.625vw, 1.5rem) means: never less than 1rem, never more than 1.5rem, and between those bounds, scale with viewport width. The vw coefficient lets you tune the rate of change. The classic trick is to compute the coefficients from two anchor points (size-at-min-viewport, size-at-max-viewport) so the curve hits both endpoints exactly.

Fluid typography pairs well with modular scale: generate the discrete scale at the small viewport, generate it again at the large viewport, then interpolate each token between the two with clamp. Utopia's generator does exactly this. The result is a scale that responds smoothly to any viewport, from 320px phones to 4K desktops, without breakpoint jumps or media-query complexity.

The trade-off: fluid typography is harder to communicate. A token called text-2xl with a fixed value of 1.5rem is one number a designer can hold in their head; the same token expressed as clamp(1.25rem, 0.95rem + 1.5vw, 1.875rem) is three numbers, two breakpoints, and a coefficient. For component libraries shared across teams, the cognitive load can outweigh the visual benefit. Many systems compromise: fluid typography for marketing pages, discrete for product surfaces.

Tokens, utilities, or both.

There are three common ways to ship a type scale. The first is utility classes: .text-xs .text-sm .text-base .text-lg ..., applied directly in markup. Tailwind, Bootstrap, and most utility-first systems work this way. Each class sets both font-size and line-height. The advantage is locality — you read the markup and know the size; no jumping to a separate stylesheet. The disadvantage is that changing one size at the system level requires editing the framework config (or, more often, the build emits new classes and old markup keeps working).

The second is CSS custom properties — --font-size-lg tokens consumed by component-level styles. The component reads font-size: var(--font-size-lg); the tokens themselves live in a :root declaration. Changing the system means editing the tokens; every component picks up the change automatically. The advantage is design-system-wide control; the disadvantage is the indirection — the markup tells you a class, the class tells you a token, the token tells you a size.

The third is a SCSS or Less map consumed at build time. @include type-scale('lg') compiles to the right declarations. Modern projects rarely use this pattern (CSS variables are more flexible and don't require a build step), but legacy codebases still do. The map ergonomics are nice for tooling — IDE autocomplete on map keys works well — at the cost of build complexity.

For most new projects, custom properties are the right default. They give you runtime theming (light/dark/contrast modes that swap tokens), they survive tree-shaking that utility classes don't always do well, and they're transparent to dev tools. The Tailwind 4 release in 2024 moved its theme primitives into CSS custom properties for exactly these reasons. The tool on this page emits all three formats so you can pick whichever fits your stack.

Hierarchy is more than just size.

A modular scale is necessary but not sufficient for a working type system. Three other axes contribute to hierarchy as much as size does, and a system that only varies size is leaving signal on the table.

Weight is the most underused tool. The same 16px text at weight 400 reads as body; at weight 600 reads as subhead; at weight 800 reads as display. Pairing a moderate scale (1.2) with two weights (400 + 700) often produces clearer hierarchy than a dramatic scale (1.5) with one weight. Variable fonts make this practically free — one font file gives you continuous weight control without download bloat.

Color and contrast create soft hierarchy. A 14px label in muted grey reads as secondary; the same label in full ink reads as primary. The contrast tool (linked above) is the right place to validate that your hierarchy choices stay accessible. WCAG AA requires 4.5:1 for normal text and 3:1 for large text (18pt+/14pt+ bold) — different size tokens may need different colors to hit the bar.

Tracking and leading (letter-spacing and line-height) compound size differences. Display sizes often want negative letter-spacing (-0.01em to -0.03em) because optical spacing increases at larger sizes; body sizes want default; small caption text sometimes wants positive tracking (+0.02em) for legibility. This tool doesn't generate tracking values, but they're worth defining as a separate token set keyed to the same scale.

Vertical rhythm ties type to spacing. Many design systems align the spacing scale to the line-height of the base size — if the body line-height is 24px, every padding and margin is a multiple of 24 (or 8, if the base 8 grid is the foundation). The result is content that visually aligns across columns and grids without per-component fudging. The Spacing Scale tool helps you generate the matching grid.

Source material.

Bringhurst's The Elements of Typographic Style (1992, 4th edition 2012) is the canonical reference for typography fundamentals — proportion, spacing, ligatures, hierarchy. The chapters on harmony and counterpoint inform every modern design-system text scale even when authors don't realise the lineage.

Tim Brown's "More Meaningful Typography" (A List Apart, 2010) introduced the modular-scale-on-the-web idea to a generation of designers. Brown later wrote Flexible Typesetting (A Book Apart, 2018) which extends the idea to fluid and responsive systems.

Mike Riethmuller's "Precise control over responsive typography" (Madebymike blog, 2015) introduced the linear-interpolation formula that powers clamp()-based fluid typography. James Gilyead and Trys Mudford packaged it into Utopia (utopia.fyi, 2020), which remains the canonical fluid-scale generator.

Spencer Mortensen's "The Typographic Scale" (2017) is a deep mathematical treatment of why integer-ratio scales feel right and how to derive them. Worth reading once if you want to understand why the major third sounds the way it does.

Roel Nieskens' "How to think about font weight" (2021) covers the weight axis in detail and is the right complement to a size-scale article. Dan Hollick's typography threads on Twitter / X cover practical type-system decisions with screenshots.

Found this useful?