Clean Markup

Preventing Typographic Widows with CSS text-wrap Balance

Preventing Typographic Widows with CSS text-wrap Balance

Responsive web design has long struggled with typographic widows and orphans in display headings. As viewports resize, fluid typography often leaves a single stranded word on the final line of an otherwise polished headline. Historically, frontend developers had to accept awkward line breaks, manually inject non-breaking spaces, or bundle heavy client-side JavaScript libraries that measured DOM bounding boxes and forced artificial breaks. With Firefox 121 joining Chrome and Safari in late 2023 to ship full support for text-wrap: balance, this visual defect is resolved directly by browser rendering engines.

The text-wrap: balance declaration instructs the layout engine to iteratively compute line breaks that distribute text evenly across each line, minimizing difference in line lengths. Because calculating optimal typographic distribution requires the browser to perform multiple layout passes, modern rendering engines enforce a 6-line limit performance heuristic—ignoring balance calculations on paragraphs longer than six lines to safeguard rendering speeds. Applying this property to headings, hero banners, and promotional cards creates visually harmonious text blocks without measuring DOM elements or running runtime scripts.

Example

h1, h2, h3, .balanced-title {
  text-wrap: balance;
}

Implementation

/* Responsive typographic hierarchy with text-wrap balance and progressive enhancement */
:root {
  --font-hero: clamp(2rem, 5vw + 1rem, 4rem);
  --font-display: clamp(1.5rem, 3vw + 0.75rem, 2.75rem);
  --line-height-tight: 1.15;
}

/* Base styles for display elements */
.hero-title {
  font-size: var(--font-hero);
  line-height: var(--line-height-tight);
  font-weight: 800;
  letter-spacing: -0.02em;
  max-inline-size: 25ch;
  
  /* Standard modern declaration: balances multi-line heading text */
  text-wrap: balance;
}

/* Card titles and promotional banners */
.section-headline {
  font-size: var(--font-display);
  line-height: 1.25;
  font-weight: 700;
  max-inline-size: 32ch;
  text-wrap: balance;
}

/* Progressive enhancement fallback check for legacy browser engines */
@supports not (text-wrap: balance) {
  /* Provide a stable typographic constraint when balancing is unavailable */
  .hero-title,
  .section-headline {
    /* Limit line width to reduce probability of single-word terminal lines */
    max-inline-size: 20ch;
  }
}

/* Note on performance: Browsers enforce a 6-line heuristic.
   For long-form prose and body paragraphs, use 'pretty' to prevent orphans without multi-pass balancing: */
.article-lead {
  font-size: 1.25rem;
  line-height: 1.6;
  text-wrap: pretty;
}

Main Point: The standardized text-wrap: balance property eliminates typographic widows on headings up to six lines through native browser engine optimization without JavaScript overhead.

Credits

Photo by Bailey Zindel on Unsplash

← Home