Home / Snippets / Typography /

Perfect leading (line-height)

Side-by-side comparison of tight, ideal, and loose leading for headings and body text.

line-height: 1.0 / 1.2

Too tight for comfort

Lines collide and descenders clip ascenders. Hard to read in paragraphs.

line-height: 1.2 / 1.6

Just right for reading

Comfortable spacing lets the eye track lines. The sweet spot for most fonts.

line-height: 1.5 / 2.0

Too loose and airy

Excessive gaps make paragraphs feel disconnected and wastes vertical space.

Widely Supported
typographyno-js

Quick implementation

/* Headings: tight leading keeps large text compact */
h1, h2, h3 {
  line-height: 1.2;
}

/* Body text: generous leading for readability */
p, li, blockquote {
  line-height: 1.6;
}

/* UI labels and small text: slightly tighter */
label, caption, .text-small {
  line-height: 1.4;
}

/* Rule of thumb:
   - Larger font → tighter line-height (1.1–1.3)
   - Smaller font → looser line-height (1.5–1.7)
   - Always use unitless values (not px or em) */

Prompt this to your LLM

Includes role, constraints, two framework variants, and edge cases to handle.

You are a senior frontend engineer specializing in web typography.

Goal: Set optimal line-height values across a type system — headings, body text, UI labels, and code blocks — for maximum readability.

Technical constraints:
- Use unitless line-height values (1.2, 1.6) — never px or em, which compound unexpectedly on child elements.
- Headings (h1–h3): line-height 1.1–1.3 (large text needs less leading).
- Body text (p, li): line-height 1.5–1.7 (the WCAG SC 1.4.12 minimum is 1.5).
- UI labels and captions: line-height 1.3–1.4.
- Code blocks: line-height 1.6–1.8 for scanability.
- Use oklch() for all color values, not hex or rgba().

Framework variant (pick one):
A) Vanilla CSS base layer — apply to element selectors and utility classes.
B) Tailwind v4 — define leading-* utilities in @theme and apply via utility classes.

Edge cases to handle:
- Multi-line headings: too-tight leading causes descender/ascender collisions.
- CJK text: requires looser leading (~1.7–1.8) due to character density.
- Inline code within paragraphs: inherits parent line-height, which is usually fine.
- WCAG 1.4.12: users must be able to override to at least 1.5× without breaking layout.

Return CSS.

Why this matters in 2026

Line-height is the single most impactful typography property for readability. Too tight and lines merge; too loose and paragraphs feel disconnected. The ideal values depend on font size — large headings need tight leading (1.1–1.3), while body text needs room to breathe (1.5–1.7). WCAG 1.4.12 now requires that users can override text spacing to at least 1.5× line-height without content loss, making correct baseline values a compliance requirement, not just an aesthetic choice.

The logic

Unitless line-height values are essential: a value like 1.6 means "1.6 times the element's own font-size," and this multiplier inherits correctly to child elements. Using line-height: 24px or 1.6em instead causes the computed value to inherit as a fixed number, breaking any child with a different font-size. The inverse relationship between font-size and line-height exists because larger text has more internal whitespace between lines by default, so you need less added leading.

Accessibility & performance

WCAG Success Criterion 1.4.12 (Text Spacing) requires that content still works when line-height is increased to at least 1.5× the font size. If your layout breaks at that value, you have a compliance gap. Using unitless values and avoiding fixed heights on text containers is the simplest way to pass. There is zero performance cost to line-height — it's resolved in a single layout pass and doesn't trigger repaints.