Skip to main content
  • Created:
  • Updated:
  • Author:
    Takeshi Takatsudo

Text Wrap: balance and pretty

The Problem

Headings and short text blocks often end up with awkward last lines — a single orphaned word dangling on its own line, creating an uneven visual shape. Developers traditionally worked around this with manual &nbsp; characters, explicit <br> tags, or JavaScript-based solutions that measure text width and reflow content. These approaches are brittle: they break at different viewport sizes, different font sizes, and in different languages. Now CSS handles this natively with the text-wrap property.

The Solution

The text-wrap property offers three values beyond the default wrap that give fine-grained control over how text breaks across lines:

  • balance — Distributes text evenly across all lines so no single line is significantly longer or shorter than others. Ideal for headings, labels, and short text blocks.
  • pretty — Prevents orphaned words on the last line of a paragraph. The browser adjusts earlier line breaks to ensure the final line has at least two words. Designed for body text.
  • stable — Ensures lines that have already been laid out don't re-wrap when editable content changes. Useful for contenteditable areas and live editing interfaces.

Core Principles

Use balance for Headings and Short Text

text-wrap: balance works by making all lines roughly equal in width. The browser calculates the optimal line breaks so that the shortest line is as long as possible. This creates a visually centered, even block of text — perfect for headings, pull quotes, and captions.

However, browsers limit balancing to approximately 6 lines for performance reasons. Beyond that threshold, the text falls back to normal wrapping.

Use pretty for Body Text

text-wrap: pretty focuses specifically on the last line. It prevents a single orphaned word from appearing alone on the final line by adjusting earlier line breaks. Unlike balance, it doesn't try to equalize all lines — it only ensures the ending looks clean.

Use stable for Editable Content

text-wrap: stable prevents previously laid-out lines from shifting when new content is typed after them. This avoids the jarring re-wrap effect in contenteditable elements and text editors.

Code Examples

Basic Usage

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

p {
text-wrap: pretty;
}

Production Typography System

/* Balance all heading levels */
h1,
h2,
h3,
h4,
h5,
h6 {
text-wrap: balance;
}

/* Prevent orphans in body text */
p,
li,
blockquote {
text-wrap: pretty;
}

/* Stable wrapping for editable areas */
[contenteditable] {
text-wrap: stable;
}
Balance vs No Balance — Heading Comparison
Pretty for Body Text — Orphan Prevention
Balance Line Limit — Short vs Long Text
Practical Typography System — Headings + Body Text
Progressive Enhancement — Graceful Degradation

CJK and Japanese Text Considerations

text-wrap: balance and text-wrap: pretty were designed with alphabetic languages in mind and behave unexpectedly with Japanese and other CJK (Chinese, Japanese, Korean) text. If you apply these properties globally to headings or paragraphs, Japanese text will often render with awkward line breaks and unusually large trailing whitespace on the right side.

Why It Breaks

In alphabetic languages, the browser uses spaces and punctuation to identify word boundaries when redistributing line breaks. Japanese has no spaces between words — every character position is a valid break point. When text-wrap: balance tries to equalize line lengths, it splits text at arbitrary character positions, producing breaks that cut through the middle of natural phrases. The result is a heading where the first line ends mid-phrase, leaving a conspicuously large gap on the right.

text-wrap: balance — English Works, Japanese Breaks

The Japanese balanced version often breaks at an unnatural position — for example splitting after a particle like 「の」 or 「な」 — because the browser has no awareness of Japanese word boundaries. The line break feels arbitrary, and the right margin of the first line becomes conspicuously large.

The word-break: auto-phrase Workaround

Chrome 119+ introduced word-break: auto-phrase, which uses the BudouX machine learning engine to identify natural phrase boundaries (文節) in Japanese text. When combined with text-wrap: balance, the browser balances around those phrase boundaries instead of arbitrary character positions.

h1,
h2,
h3 {
text-wrap: balance;
word-break: auto-phrase; /* Chrome 119+ — improves Japanese line breaks */
}
word-break: auto-phrase — Japanese Phrase-Aware Balancing (Chrome 119+)

Note that word-break: auto-phrase requires lang="ja" on the element or an ancestor to activate Japanese phrase detection. Without the lang attribute, the property has no effect. Firefox does not yet support auto-phrase. Safari support is limited — check current browser compatibility before relying on it.

Locale-Scoped Fallback Pattern

For Japanese or multilingual sites, the safest approach is to reset text-wrap for Japanese content via the lang attribute selector:

/* Apply balance globally */
h1,
h2,
h3 {
text-wrap: balance;
word-break: auto-phrase; /* helps in Chrome */
}

/* Reset for Japanese where balance misbehaves without auto-phrase support */
[lang="ja"] :is(h1, h2, h3) {
text-wrap: initial;
}

/* Re-enable balance in Chrome which supports auto-phrase */
@supports (word-break: auto-phrase) {
[lang="ja"] :is(h1, h2, h3) {
text-wrap: balance;
}
}
Locale-Scoped Pattern — Reset for Japanese, Balance for English

Summary

PropertyEnglishJapanese
text-wrap: balanceWorks wellBreaks at arbitrary character positions
text-wrap: prettyWorks wellLargely harmless but orphan concept doesn't map well to CJK
word-break: auto-phraseNo effectImproves phrase-aware breaking (Chrome 119+ only)

Recommendation: For Japanese or multilingual projects, avoid applying text-wrap: balance to headings unconditionally. Either skip it for Japanese content, use the locale-scoped @supports pattern above, or accept that the improvement will only appear in Chrome.

Browser Support

  • text-wrap: balance — Supported in Chrome 114+, Edge 114+, Firefox 121+, and Safari 17.5+. Widely available as of 2025.
  • text-wrap: pretty — Supported in Chrome 117+, Edge 117+, and Safari 17.4+. Firefox support is still pending as of early 2026.
  • text-wrap: stable — Supported in Chrome 120+, Edge 120+, and Firefox 121+. Safari support is pending.

All three values degrade gracefully — unsupported browsers simply use the default text-wrap: wrap behavior, so there is no risk in applying them today.

Common AI Mistakes

  • Applying text-wrap: balance to long body text paragraphs — it only works on blocks of approximately 6 lines or fewer, and even when it does apply, it creates an unnaturally narrow text block
  • Using JavaScript to calculate line breaks and insert <br> tags when text-wrap: balance solves the same problem natively
  • Inserting &nbsp; between the last two words to prevent orphans — this is fragile and breaks at different viewport widths. Use text-wrap: pretty instead
  • Confusing text-wrap: balance with text-align: center — balance adjusts line break positions to equalize line lengths, it does not change alignment
  • Not setting text-wrap: balance on heading elements by default — this should be a baseline style for all heading levels
  • Applying text-wrap: balance to elements that need a specific width, like navigation items or badges — balance can change the intrinsic width of the element unexpectedly

When to Use

text-wrap: balance

  • Headings (h1 through h6)
  • Pull quotes and blockquote text
  • Captions and figcaptions
  • Card titles and hero text
  • Any short text block (6 lines or fewer) where visual symmetry matters

text-wrap: pretty

  • Body paragraphs
  • List items with wrapping text
  • Descriptions and summaries
  • Any long-form text where you want to avoid a single orphaned word on the last line

text-wrap: stable

  • contenteditable elements
  • Live text editors and input areas
  • Chat message composition fields
  • Any context where text is being actively edited and re-wrapping would be disruptive

References