Readability
Optimizing for reading — line length (measure), line height (leading), paragraph spacing, text alignment, hyphenation, and reading patterns (F-pattern, Z-pattern)
When to Use
- Setting body text styles for any content-heavy page (documentation, blogs, articles)
- Configuring
max-width on text containers to control line length
- Choosing
line-height values for body text, headings, and captions
- Deciding between left, center, right, or justified text alignment
- Debugging layouts where users report text is "hard to read" or "tiring"
- Designing for screens where sustained reading is the primary activity
Instructions
Set line length (measure) to 45-75 characters per line. This is the single most impactful readability setting. The research is unambiguous: lines shorter than 45 characters cause excessive line breaks and choppy reading; lines longer than 75 characters cause the eye to lose its place when returning to the left margin.
Concrete values for common body sizes:
| Font Size |
Font |
Ideal Max-Width |
~Characters |
| 16px |
Inter |
640-680px |
65-70 |
| 16px |
Georgia |
600-640px |
62-67 |
| 18px |
system-ui |
700-740px |
63-68 |
| 21px |
Georgia |
780-820px |
60-65 |
Decision procedure: Set max-width on your text container. Paste a paragraph of real content. Count characters in the longest line. Adjust until you hit 60-70 characters. The exact pixel value depends on font, size, and letter-spacing — there is no universal pixel number.
Two-column exception: When text is set in narrow columns (sidebars, cards, multi-column layouts), 35-45 characters per line is acceptable because the vertical distance between lines is shorter, making the return sweep easier.
Set line-height (leading) based on context. Leading is the vertical distance between baselines. Too tight and lines collide visually; too loose and the text disintegrates into separate strips.
| Context |
Line-Height |
Rationale |
| Body text (16-18px) |
1.5-1.65 |
Optimal for sustained reading |
| Large body (20-24px) |
1.4-1.5 |
Larger text needs proportionally less leading |
| Headings (24-48px) |
1.1-1.25 |
Tight leading keeps multi-line headings cohesive |
| Display text (48px+) |
1.0-1.1 |
Very large text looks disconnected with normal leading |
| Captions (12-14px) |
1.4-1.5 |
Small text needs generous leading for legibility |
| Code blocks |
1.5-1.7 |
Programmers scan vertically; generous leading aids line identification |
The inverse relationship: as font size increases, optimal line-height ratio decreases. Stripe demonstrates this: body at 16px uses line-height 1.40, but display headlines at 56px use line-height 1.03. The absolute leading increases (22.4px vs 57.7px) but the ratio tightens dramatically.
Set paragraph spacing to 0.5-1.0em between paragraphs. Use margin-bottom on paragraphs, not double line breaks. The spacing should be large enough to signal "new paragraph" but not so large that the text feels disconnected.
- Standard:
margin-bottom: 1em (one blank line's worth) — used by most systems
- Compact:
margin-bottom: 0.5em — for data-dense interfaces or when vertical space is premium
- Generous:
margin-bottom: 1.5em — for editorial/literary content with wide line spacing
- Rule: paragraph spacing should be noticeably larger than line-height but smaller than section spacing
Default to left-aligned text for body content in LTR languages. Alignment choices:
- Left (start): Default for all body text. The ragged right edge is natural and provides unique line shapes that help the eye track position. Always use for body text.
- Center: Only for short text blocks (1-3 lines) — headings, hero text, call-to-action buttons. Never for paragraphs. Centered body text destroys the left anchor the eye uses for line returns.
- Right (end): Reserved for specific UI contexts — numeric columns in tables (right-align numbers for decimal alignment), dates, prices. Never for body text.
- Justified: Creates clean block edges but introduces variable word spacing ("rivers" of white space) unless the browser supports quality hyphenation. Use only when
hyphens: auto is set AND the language has good hyphenation dictionaries (English, German, French — yes; Japanese, Chinese — not applicable). Even then, prefer left-aligned.
Understand reading patterns to structure content. Eye-tracking research (Nielsen Norman Group) identified two primary scanning patterns:
F-Pattern (content-heavy pages):
- Users read the first line or two fully (horizontal bar 1)
- Eyes drop down and read a shorter horizontal segment (horizontal bar 2)
- Users scan the left edge vertically, picking up first words of each line/section
- Implication: put the most important information in the first two lines of each section and at the start of each paragraph. Front-load sentences with key terms.
Z-Pattern (sparse layouts, landing pages):
- Eyes move: top-left -> top-right -> diagonal to bottom-left -> bottom-right
- Implication: place the logo/brand top-left, the CTA top-right, supporting info bottom-left, primary action bottom-right
Optimize the relationship between font size, line-height, and measure. These three properties are interdependent — changing one requires reconsidering the others:
- Increase font size -> line-height ratio can decrease, but measure (px) should increase to maintain character count
- Increase line-height -> measure can increase slightly (more leading makes longer lines easier to track)
- Decrease measure -> line-height can decrease slightly (shorter lines need less leading because the return sweep is shorter)
Details
Readability Configurations from Leading Design Systems
Stripe Documentation
- Body: 16px, Inter, line-height 1.625 (26px), max-width
680px (70 characters)
- Why it works: the generous 1.625 line-height compensates for Inter's tall x-height, which can make lines feel cramped at standard 1.5 leading. The 680px max-width keeps lines at exactly 68-72 characters.
Apple Developer Documentation
- Body: 17px, SF Pro Text, line-height 1.47 (25px), max-width
800px (72 characters)
- Apple uses a slightly larger body size (17px vs the industry standard 16px) and a moderately generous line-height. The wider max-width is acceptable because the larger font size maintains character count within range.
Medium / Reading-Optimized Platforms
- Body: 21px, charter/Georgia fallback, line-height 1.58 (33px), max-width
680px (52 characters)
- Medium uses an unusually large body size with generous leading. The result is a "book-like" reading experience — fewer characters per line (52 vs the recommended 65) creates a faster-paced rhythm appropriate for the platform's short-to-medium article format.
Material Design 3
- Body Large: 16px, Roboto, line-height 1.5 (24px)
- Body Medium: 14px, Roboto, line-height 1.43 (20px)
- Body Small: 12px, Roboto, line-height 1.33 (16px)
- Material uses tighter line-heights as sizes decrease — the opposite of best practice for extended reading. This works because Material targets UI labels and short descriptions, not sustained reading.
The Measure-Leading Interaction
Practical table for common configurations:
| Scenario |
Font Size |
Line-Height |
Max-Width |
Chars/Line |
| Documentation |
16px |
1.6 |
680px |
68 |
| Blog/editorial |
18px |
1.7 |
720px |
62 |
| Literary reading |
21px |
1.6 |
680px |
52 |
| Dashboard text |
14px |
1.5 |
480px |
55 |
| Card description |
14px |
1.45 |
320px |
38 |
| Code block |
14px |
1.6 |
880px |
100 |
Code blocks are the exception to the 75-character rule — developers expect wide lines and horizontal scroll, and the monospace font provides character-level position tracking that proportional fonts cannot.
Hyphenation and Justification
Justified text is the default in print because page layout engines (InDesign, TeX) have sophisticated paragraph-level justification algorithms. Web browsers do not — they justify line by line, producing inferior results.
If you must use justified text on the web:
.justified-text {
text-align: justify;
hyphens: auto;
-webkit-hyphens: auto;
word-break: break-word; /* prevent overflow on long words */
overflow-wrap: break-word;
max-width: 680px; /* justified text requires controlled measure */
}
Even with these settings, justified web text will have visible rivers in narrow columns. If the container is narrower than 500px, never justify.
Anti-Patterns
Full-width body text. Setting body text at width: 100% on a 1920px monitor produces lines of 160+ characters. The eye cannot track back to the correct next line after such a long horizontal sweep. This is the most common readability failure on the web. Fix: max-width: 65ch or a pixel equivalent based on your font.
Cramped leading. Line-height of 1.0-1.2 for body text (16px font, 16-19px line-height) causes ascenders and descenders of adjacent lines to collide visually. The text feels dense, claustrophobic, and tiring. Common cause: inheriting line-height: 1.2 from a CSS reset that was designed for headings, not body text. Fix: set body line-height explicitly to 1.5-1.65.
Justified text without hyphenation. Justified text distributes extra space between words to fill the line. Without hyphenation, long words force enormous gaps. On narrow columns (300-400px), individual lines can have gaps wider than the words themselves, creating "rivers" of white space that flow vertically through the paragraph. Fix: either add hyphens: auto or switch to text-align: left.
Centered body paragraphs. Centering more than 3 lines of text destroys the fixed left edge that the eye uses to locate the start of each new line. Reading speed drops by 10-20% (per Nielsen Norman Group research). Fix: center only headings, short taglines, and CTAs. Left-align all body paragraphs.
Uniform line-height across all sizes. Setting line-height: 1.5 globally means a 48px heading gets 72px of leading (excessive, text floats apart) while 12px captions get 18px (possibly too tight). Fix: define line-height per text role, with the ratio decreasing as font size increases.
Real-World Examples
Fixing a Documentation Site
Before: 14px body, line-height 1.3, full-width (1200px container), justified alignment. Users reported "eye strain" and "losing my place."
After: 16px body, line-height 1.6, max-width 680px centered in the layout, left-aligned. Bounce rate decreased 15%, average time on page increased 25%. The changes were purely typographic — no content, layout, or color changes.
Optimizing a Reading App
A Kindle-style web reader tested 3 configurations with 500 users:
- Config A: 16px, line-height 1.5, 600px width (65 chars) — 4.2 min average reading time
- Config B: 18px, line-height 1.6, 660px width (60 chars) — 3.9 min average reading time
- Config C: 21px, line-height 1.7, 680px width (52 chars) — 4.0 min average reading time
Config B won on reading speed. The 18px size with 1.6 leading hit the optimal balance — large enough for comfortable reading without reducing characters-per-line below 55.
Source
- Bringhurst, Robert. The Elements of Typographic Style — on measure and leading
- Butterick, Matthew. Butterick's Practical Typography — line length, line spacing, text alignment
- Nielsen Norman Group — "F-Shaped Pattern for Reading Web Content" (2006, updated 2017)
- Dyson, M.C. & Haselgrove, M. (2001). "The influence of reading speed and line length on the effectiveness of reading from screen"
- WCAG 2.1 Success Criterion 1.4.8 — Visual Presentation (recommended line length, leading, alignment)
Process
- Evaluate — Measure the current line length (characters per line), line-height ratio, and paragraph spacing. Identify the reading pattern appropriate for the page type (F-pattern for content, Z-pattern for sparse layouts).
- Apply — Set max-width to achieve 45-75 characters per line. Set line-height appropriate to font size (1.5-1.65 for body, 1.1-1.25 for headings). Left-align body text. Add paragraph spacing at 0.5-1.0em.
- Verify — Count characters per line with real content. Check that the squint test shows clear paragraph separation. Confirm that line-height produces no visual collision between ascenders and descenders.
Harness Integration
This is a knowledge skill. When activated, it provides readability optimization expertise for text layout decisions. Use these principles when setting max-width, line-height, text-align, margin-bottom, and hyphens properties. Cross-reference with design-responsive-type for viewport-adaptive adjustments and design-content-density for information-rich interfaces.
Success Criteria
- Body text line length is 45-75 characters (measured with actual content, not estimated)
- Line-height for body text is between 1.5 and 1.65
- Line-height for headings is between 1.1 and 1.25
- Body text is left-aligned (not centered or justified without hyphenation)
- Paragraph spacing is between 0.5em and 1.0em
- No text container spans full viewport width without a max-width constraint
1---2name: design-readability3description: Readability4---5# Readability67> Optimizing for reading — line length (measure), line height (leading), paragraph spacing, text alignment, hyphenation, and reading patterns (F-pattern, Z-pattern)89## When to Use1011- Setting body text styles for any content-heavy page (documentation, blogs, articles)12- Configuring `max-width` on text containers to control line length13- Choosing `line-height` values for body text, headings, and captions14- Deciding between left, center, right, or justified text alignment15- Debugging layouts where users report text is "hard to read" or "tiring"16- Designing for screens where sustained reading is the primary activity1718## Instructions19201. **Set line length (measure) to 45-75 characters per line.** This is the single most impactful readability setting. The research is unambiguous: lines shorter than 45 characters cause excessive line breaks and choppy reading; lines longer than 75 characters cause the eye to lose its place when returning to the left margin.2122 **Concrete values for common body sizes:**23 | Font Size | Font | Ideal Max-Width | ~Characters |24 |-----------|------|----------------|-------------|25 | 16px | Inter | 640-680px | 65-70 |26 | 16px | Georgia | 600-640px | 62-67 |27 | 18px | system-ui | 700-740px | 63-68 |28 | 21px | Georgia | 780-820px | 60-65 |2930 **Decision procedure**: Set `max-width` on your text container. Paste a paragraph of real content. Count characters in the longest line. Adjust until you hit 60-70 characters. The exact pixel value depends on font, size, and letter-spacing — there is no universal pixel number.3132 **Two-column exception**: When text is set in narrow columns (sidebars, cards, multi-column layouts), 35-45 characters per line is acceptable because the vertical distance between lines is shorter, making the return sweep easier.33342. **Set line-height (leading) based on context.** Leading is the vertical distance between baselines. Too tight and lines collide visually; too loose and the text disintegrates into separate strips.3536 | Context | Line-Height | Rationale |37 | -------------------- | ----------- | ---------------------------------------------------------------------- |38 | Body text (16-18px) | 1.5-1.65 | Optimal for sustained reading |39 | Large body (20-24px) | 1.4-1.5 | Larger text needs proportionally less leading |40 | Headings (24-48px) | 1.1-1.25 | Tight leading keeps multi-line headings cohesive |41 | Display text (48px+) | 1.0-1.1 | Very large text looks disconnected with normal leading |42 | Captions (12-14px) | 1.4-1.5 | Small text needs generous leading for legibility |43 | Code blocks | 1.5-1.7 | Programmers scan vertically; generous leading aids line identification |4445 **The inverse relationship**: as font size increases, optimal line-height ratio decreases. Stripe demonstrates this: body at 16px uses line-height 1.40, but display headlines at 56px use line-height 1.03. The absolute leading increases (22.4px vs 57.7px) but the ratio tightens dramatically.46473. **Set paragraph spacing to 0.5-1.0em between paragraphs.** Use `margin-bottom` on paragraphs, not double line breaks. The spacing should be large enough to signal "new paragraph" but not so large that the text feels disconnected.48 - **Standard**: `margin-bottom: 1em` (one blank line's worth) — used by most systems49 - **Compact**: `margin-bottom: 0.5em` — for data-dense interfaces or when vertical space is premium50 - **Generous**: `margin-bottom: 1.5em` — for editorial/literary content with wide line spacing51 - **Rule**: paragraph spacing should be noticeably larger than line-height but smaller than section spacing52534. **Default to left-aligned text for body content in LTR languages.** Alignment choices:54 - **Left (start)**: Default for all body text. The ragged right edge is natural and provides unique line shapes that help the eye track position. Always use for body text.55 - **Center**: Only for short text blocks (1-3 lines) — headings, hero text, call-to-action buttons. Never for paragraphs. Centered body text destroys the left anchor the eye uses for line returns.56 - **Right (end)**: Reserved for specific UI contexts — numeric columns in tables (right-align numbers for decimal alignment), dates, prices. Never for body text.57 - **Justified**: Creates clean block edges but introduces variable word spacing ("rivers" of white space) unless the browser supports quality hyphenation. Use only when `hyphens: auto` is set AND the language has good hyphenation dictionaries (English, German, French — yes; Japanese, Chinese — not applicable). Even then, prefer left-aligned.58595. **Understand reading patterns to structure content.** Eye-tracking research (Nielsen Norman Group) identified two primary scanning patterns:6061 **F-Pattern** (content-heavy pages):62 - Users read the first line or two fully (horizontal bar 1)63 - Eyes drop down and read a shorter horizontal segment (horizontal bar 2)64 - Users scan the left edge vertically, picking up first words of each line/section65 - **Implication**: put the most important information in the first two lines of each section and at the start of each paragraph. Front-load sentences with key terms.6667 **Z-Pattern** (sparse layouts, landing pages):68 - Eyes move: top-left -> top-right -> diagonal to bottom-left -> bottom-right69 - **Implication**: place the logo/brand top-left, the CTA top-right, supporting info bottom-left, primary action bottom-right70716. **Optimize the relationship between font size, line-height, and measure.** These three properties are interdependent — changing one requires reconsidering the others:72 - **Increase font size** -> line-height ratio can decrease, but measure (px) should increase to maintain character count73 - **Increase line-height** -> measure can increase slightly (more leading makes longer lines easier to track)74 - **Decrease measure** -> line-height can decrease slightly (shorter lines need less leading because the return sweep is shorter)7576## Details7778### Readability Configurations from Leading Design Systems7980**Stripe Documentation**8182- Body: 16px, Inter, line-height 1.625 (26px), max-width ~680px (~70 characters)83- Why it works: the generous 1.625 line-height compensates for Inter's tall x-height, which can make lines feel cramped at standard 1.5 leading. The 680px max-width keeps lines at exactly 68-72 characters.8485**Apple Developer Documentation**8687- Body: 17px, SF Pro Text, line-height 1.47 (25px), max-width ~800px (~72 characters)88- Apple uses a slightly larger body size (17px vs the industry standard 16px) and a moderately generous line-height. The wider max-width is acceptable because the larger font size maintains character count within range.8990**Medium / Reading-Optimized Platforms**9192- Body: 21px, charter/Georgia fallback, line-height 1.58 (33px), max-width ~680px (~52 characters)93- Medium uses an unusually large body size with generous leading. The result is a "book-like" reading experience — fewer characters per line (52 vs the recommended 65) creates a faster-paced rhythm appropriate for the platform's short-to-medium article format.9495**Material Design 3**9697- Body Large: 16px, Roboto, line-height 1.5 (24px)98- Body Medium: 14px, Roboto, line-height 1.43 (20px)99- Body Small: 12px, Roboto, line-height 1.33 (16px)100- Material uses tighter line-heights as sizes decrease — the opposite of best practice for extended reading. This works because Material targets UI labels and short descriptions, not sustained reading.101102### The Measure-Leading Interaction103104Practical table for common configurations:105106| Scenario | Font Size | Line-Height | Max-Width | Chars/Line |107| ---------------- | --------- | ----------- | --------- | ---------- |108| Documentation | 16px | 1.6 | 680px | 68 |109| Blog/editorial | 18px | 1.7 | 720px | 62 |110| Literary reading | 21px | 1.6 | 680px | 52 |111| Dashboard text | 14px | 1.5 | 480px | 55 |112| Card description | 14px | 1.45 | 320px | 38 |113| Code block | 14px | 1.6 | 880px | 100 |114115Code blocks are the exception to the 75-character rule — developers expect wide lines and horizontal scroll, and the monospace font provides character-level position tracking that proportional fonts cannot.116117### Hyphenation and Justification118119Justified text is the default in print because page layout engines (InDesign, TeX) have sophisticated paragraph-level justification algorithms. Web browsers do not — they justify line by line, producing inferior results.120121If you must use justified text on the web:122123```css124.justified-text {125 text-align: justify;126 hyphens: auto;127 -webkit-hyphens: auto;128 word-break: break-word; /* prevent overflow on long words */129 overflow-wrap: break-word;130 max-width: 680px; /* justified text requires controlled measure */131}132```133134Even with these settings, justified web text will have visible rivers in narrow columns. If the container is narrower than 500px, never justify.135136### Anti-Patterns1371381. **Full-width body text.** Setting body text at `width: 100%` on a 1920px monitor produces lines of 160+ characters. The eye cannot track back to the correct next line after such a long horizontal sweep. This is the most common readability failure on the web. Fix: `max-width: 65ch` or a pixel equivalent based on your font.1391402. **Cramped leading.** Line-height of 1.0-1.2 for body text (16px font, 16-19px line-height) causes ascenders and descenders of adjacent lines to collide visually. The text feels dense, claustrophobic, and tiring. Common cause: inheriting `line-height: 1.2` from a CSS reset that was designed for headings, not body text. Fix: set body line-height explicitly to 1.5-1.65.1411423. **Justified text without hyphenation.** Justified text distributes extra space between words to fill the line. Without hyphenation, long words force enormous gaps. On narrow columns (300-400px), individual lines can have gaps wider than the words themselves, creating "rivers" of white space that flow vertically through the paragraph. Fix: either add `hyphens: auto` or switch to `text-align: left`.1431444. **Centered body paragraphs.** Centering more than 3 lines of text destroys the fixed left edge that the eye uses to locate the start of each new line. Reading speed drops by 10-20% (per Nielsen Norman Group research). Fix: center only headings, short taglines, and CTAs. Left-align all body paragraphs.1451465. **Uniform line-height across all sizes.** Setting `line-height: 1.5` globally means a 48px heading gets 72px of leading (excessive, text floats apart) while 12px captions get 18px (possibly too tight). Fix: define line-height per text role, with the ratio decreasing as font size increases.147148### Real-World Examples149150**Fixing a Documentation Site**151Before: 14px body, line-height 1.3, full-width (1200px container), justified alignment. Users reported "eye strain" and "losing my place."152After: 16px body, line-height 1.6, max-width 680px centered in the layout, left-aligned. Bounce rate decreased 15%, average time on page increased 25%. The changes were purely typographic — no content, layout, or color changes.153154**Optimizing a Reading App**155A Kindle-style web reader tested 3 configurations with 500 users:156157- **Config A**: 16px, line-height 1.5, 600px width (65 chars) — 4.2 min average reading time158- **Config B**: 18px, line-height 1.6, 660px width (60 chars) — 3.9 min average reading time159- **Config C**: 21px, line-height 1.7, 680px width (52 chars) — 4.0 min average reading time160 Config B won on reading speed. The 18px size with 1.6 leading hit the optimal balance — large enough for comfortable reading without reducing characters-per-line below 55.161162## Source163164- Bringhurst, Robert. _The Elements of Typographic Style_ — on measure and leading165- Butterick, Matthew. _Butterick's Practical Typography_ — line length, line spacing, text alignment166- Nielsen Norman Group — "F-Shaped Pattern for Reading Web Content" (2006, updated 2017)167- Dyson, M.C. & Haselgrove, M. (2001). "The influence of reading speed and line length on the effectiveness of reading from screen"168- WCAG 2.1 Success Criterion 1.4.8 — Visual Presentation (recommended line length, leading, alignment)169170## Process1711721. **Evaluate** — Measure the current line length (characters per line), line-height ratio, and paragraph spacing. Identify the reading pattern appropriate for the page type (F-pattern for content, Z-pattern for sparse layouts).1732. **Apply** — Set max-width to achieve 45-75 characters per line. Set line-height appropriate to font size (1.5-1.65 for body, 1.1-1.25 for headings). Left-align body text. Add paragraph spacing at 0.5-1.0em.1743. **Verify** — Count characters per line with real content. Check that the squint test shows clear paragraph separation. Confirm that line-height produces no visual collision between ascenders and descenders.175176## Harness Integration177178This is a knowledge skill. When activated, it provides readability optimization expertise for text layout decisions. Use these principles when setting `max-width`, `line-height`, `text-align`, `margin-bottom`, and `hyphens` properties. Cross-reference with `design-responsive-type` for viewport-adaptive adjustments and `design-content-density` for information-rich interfaces.179180## Success Criteria181182- Body text line length is 45-75 characters (measured with actual content, not estimated)183- Line-height for body text is between 1.5 and 1.65184- Line-height for headings is between 1.1 and 1.25185- Body text is left-aligned (not centered or justified without hyphenation)186- Paragraph spacing is between 0.5em and 1.0em187- No text container spans full viewport width without a max-width constraint