Harness-engineering design-readability

Readability

install
source · Clone the upstream repo
git clone https://github.com/Intense-Visions/harness-engineering
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/Intense-Visions/harness-engineering "$T" && mkdir -p ~/.claude/skills && cp -r "$T/agents/skills/codex/design-readability" ~/.claude/skills/intense-visions-harness-engineering-design-readability-bd9b70 && rm -rf "$T"
manifest: agents/skills/codex/design-readability/SKILL.md
source content

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

  1. 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 SizeFontIdeal Max-Width~Characters
    16pxInter640-680px65-70
    16pxGeorgia600-640px62-67
    18pxsystem-ui700-740px63-68
    21pxGeorgia780-820px60-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.

  2. 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.

    ContextLine-HeightRationale
    Body text (16-18px)1.5-1.65Optimal for sustained reading
    Large body (20-24px)1.4-1.5Larger text needs proportionally less leading
    Headings (24-48px)1.1-1.25Tight leading keeps multi-line headings cohesive
    Display text (48px+)1.0-1.1Very large text looks disconnected with normal leading
    Captions (12-14px)1.4-1.5Small text needs generous leading for legibility
    Code blocks1.5-1.7Programmers 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.

  3. 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
  4. 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.
  5. 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
  6. 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:

ScenarioFont SizeLine-HeightMax-WidthChars/Line
Documentation16px1.6680px68
Blog/editorial18px1.7720px62
Literary reading21px1.6680px52
Dashboard text14px1.5480px55
Card description14px1.45320px38
Code block14px1.6880px100

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

  1. 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.

  2. 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.

  3. 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
    .

  4. 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.

  5. 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

  1. 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).
  2. 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.
  3. 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