two values, two line break problems
text-wrap balance and text-wrap pretty solve two different line break problems: balance evens out short headings across all lines, pretty prevents single words from being left alone at the end of body text paragraphs. Using both values deliberately instead of interchangeably yields noticeably cleaner typography without any extra JavaScript.
Table of Contents
- 1. Why line breaking is a problem at all
- 2. text-wrap: balance in detail
- 3. text-wrap: pretty in detail
- 4. The real difference: goal and algorithm
- 5. Understanding balance's six line limit
- 6. Combining both values in the same layout
- 7. Fallback strategy for older browsers
- 8. Performance and reflow costs
- 9. Use cases compared directly
- 10. Summary
- 11. FAQ
1. Why line breaking is a problem at all
The default line breaking behavior on the web follows a simple, greedy algorithm: words are packed into a line until no more fit, then the next line begins. This behavior is fast to compute but regularly produces ugly results, such as a heading where only a single short word slips onto the last line, or a body text paragraph whose last line consists of just one word. text-wrap with the values balance and pretty addresses exactly this problem, without needing JavaScript or manual <br> tags.
These line breaking problems have been known in classic print typography for decades and are solved there through line break optimization by professional typesetting software that computes the entire paragraph globally. The web long had no access to comparable algorithms, because CSS only knew the greedy line break. With text-wrap, a piece of that print quality moves directly into the browser, without server side precomputation or a build step.
Traditionally, designers either ignored such wrapping problems or fixed them with hard coded line breaks in the markup, which immediately breaks on responsive layouts as soon as the available width changes. A manual <br> tuned for desktop often looks disastrous on mobile devices. text-wrap solves this problem declaratively and responsively, the browser recalculates the optimal break at every width without developers having to write a separate solution for each breakpoint.
This responsive recalculation happens automatically on every reflow, for example when rotating a mobile device from portrait to landscape or when resizing a window on desktop, without needing an additional event listener or media query.
Important to understand: balance and pretty are not interchangeable synonyms for "nicer wrapping", but two algorithms with different goals and different usage boundaries. Treating them the same wastes one of the two values in the wrong place in the layout.
Both values are part of the broader CSS property text-wrap, which additionally knows the values wrap as the default behavior, nowrap for fully suppressing breaks, and stable for consistent breaks during incremental text changes. For typographic fine tuning, however, balance and pretty are the two practically relevant values.
Historically, designers had to fall back on JavaScript libraries for balanced headings, libraries that used a ResizeObserver to watch an element's width and manually inserted line breaks on every size change. These solutions worked but added extra script weight, delayed first render, and had to be retested on every redesign. text-wrap solves the same problem natively in the browser, without extra JavaScript and without layout shift from subsequent break correction.
2. text-wrap: balance in detail
text-wrap: balance distributes the available text across all lines of a block so that every line has as similar a length as possible. To do this, the browser first computes the total number of lines using the standard algorithm, then redistributes the text so that no line is noticeably shorter or longer than the others. The result is especially visible on multi line headings: instead of one long first line and a single word on the second line, two evenly balanced lines are produced.
balance is explicitly designed for short, prominent text blocks, meaning headings, hero claims, quotes, and card titles. The algorithm is more computationally expensive than the standard break, because it has to try several wrapping variants to find the most balanced distribution. For this reason browsers cap balance at a maximum line count, the value is not intended for long body text paragraphs and would cause noticeable performance costs without that limit.
/* balance evens out heading line lengths */
h1, h2, h3 {
text-wrap: balance;
}
.hero-claim {
font-size: clamp(1.75rem, 4vw + 1rem, 3rem);
text-wrap: balance;
max-width: 24ch;
}
/* Without balance: greedy wrap can leave one word alone
"Modern web development for" / "ambitious teams" */
/* With balance: lines are evened out
"Modern web" / "development for" / "ambitious teams" */
3. text-wrap: pretty in detail
text-wrap: pretty pursues a different goal than balance: instead of making every line the same length, pretty specifically prevents single, unattractively isolated words at the end of a paragraph, what classic typography terminology calls widows or orphans. To do this, the algorithm looks at more than just the last line and computes whether a different break further up in the paragraph can prevent the lonely last word without noticeably lengthening the remaining lines.
Because pretty does not try to make every line equally long but only specifically fixes the last line problem, the computational cost is lower than for balance, and the browser therefore allows pretty for long body text paragraphs without any line limit. That makes pretty the right choice for article text, product descriptions and long paragraphs, while balance remains reserved for short, prominent text blocks.
The name pretty is deliberately general, because the exact heuristic can differ slightly between browser implementations, but the overarching goal always stays the same: no single, visually isolated word at the end of a paragraph. For developers this means not relying on pixel identical behavior across all browsers, but trusting the fundamental improvement over the standard break.
/* pretty avoids orphaned single words in long paragraphs */
p, li, blockquote {
text-wrap: pretty;
}
.article-body p {
max-width: 70ch;
text-wrap: pretty;
}
/* Without pretty: last line might read just "team."
With pretty: the browser reflows earlier lines to avoid
leaving a single orphaned word at the end */
A common misconception among teams new to text-wrap is assuming pretty is simply a weaker variant of balance. In fact they are two completely independent algorithms with their own specification, neither is a subset of the other. pretty can, in certain cases, perform even more elaborate local recalculations than balance on a very short heading, because pretty potentially takes several preceding lines into account to solve the trailing word problem.
4. The real difference: goal and algorithm
The core difference between balance and pretty lies in the optimization goal. balance optimizes globally across the whole block: all line lengths should be as similar as possible. pretty optimizes locally at the end of the paragraph: only the last line problem should be solved, the rest of the text stays with the standard break. This different goal explains why balance would be impractical for long paragraphs, computing an even distribution across twenty lines would be computationally expensive and would barely improve the layout visibly.
For practical work it is enough to remember: balance thinks in blocks, pretty thinks in line endings.
A second difference concerns the line count limit. balance is implicitly capped by browser vendors at a small number of lines, usually somewhere between four and ten, depending on the implementation. If a text block exceeds this internal limit, the browser automatically falls back to the standard break without any visible error. pretty knows no such limit and works regardless of text length, because the algorithm only intervenes locally at the end of the paragraph.
5. Understanding balance's six line limit
Most implementations of text-wrap: balance internally cap the computation at roughly six lines. This limit is not an arbitrary number but a deliberate performance boundary: the balancing algorithm has to try several possible break combinations, and the number of combinations grows sharply with the line count. For a three line heading this is trivial, for a twenty line paragraph it would be a noticeable performance factor during initial rendering and on every reflow caused by a window resize.
In practice this means: if balance is accidentally applied to a long body text paragraph instead of a heading, no error is noticed, only that the effect simply stops applying above the line boundary and the browser silently falls back to normal wrapping. This makes debugging harder, because no error and no warning appears in the console. A good rule of thumb in practice: only apply balance to elements that typically have no more than three to four lines, meaning headings, card titles and short quotes.
A simple test in developer tools helps identify this boundary quickly: temporarily lengthen an element's text content substantially and observe at what point the line distribution becomes uneven again. The point where that happens marks the practical upper bound for balance in that particular layout and font.
6. Combining both values in the same layout
In most real projects, balance and pretty are used together, but at different places within the same layout. A typical article page applies balance to the main heading and all subheadings, while pretty is applied to the body text paragraphs. This combination addresses both wrapping problems exactly where they actually occur, without a single value being misused for both tasks.
A practical approach for design systems is to automate this assignment through utility classes or directly through element selectors, instead of deciding manually for every new text block. That way the rule stays consistent across the whole project: headings automatically get balance, body text automatically gets pretty, without any single developer having to redefine it for every new component.
For Tailwind based projects this assignment can additionally be expressed directly as a utility class, such as text-balance and text-pretty, which internally set exactly the text-wrap values shown here. That lets the decision be made visibly per component in the markup, without writing an additional CSS rule for every exception.
/* Typical project setup: balance for headings, pretty for body text */
h1, h2, h3, h4,
.card-title,
blockquote {
text-wrap: balance;
}
p, li, dd,
figcaption,
.article-body {
text-wrap: pretty;
}
/* Long headings automatically fall back to normal wrap
once they exceed the internal line limit, no manual override needed */
A further advantage of this separation by element type is that the rule automatically carries over to new components as soon as they use the same classes or selectors. A newly added card layout with a .card-title class inherits balance automatically, without a developer having to redefine the rule, which makes design system consistency considerably easier over time.
7. Fallback strategy for older browsers
Because text-wrap: balance and text-wrap: pretty are comparatively new CSS values, a defensive fallback strategy makes sense, even though both values work in a progressive enhancement manner. Browsers that do not know the value ignore the entire declaration and keep the standard break, so no rendering error occurs, only a less optimized but perfectly functional line break. That is exactly why text-wrap can be used in production without an @supports check.
For projects that need additional control over balance's line count limit, combining it with @supports (text-wrap: balance) can make sense, to specifically define alternative styles for browsers without support, such as a tighter max-width that produces more evenly balanced lines even without the balancing algorithm.
A further advantage of this fallback strategy: it works regardless of whether the user runs a current browser or one several years old, since the underlying max-width constraint always applies and is only supplemented by the finer balancing computation in supporting browsers. So there is never a state where the typography looks objectively worse than without text-wrap at all.
/* Optional: tighter max-width as a fallback for browsers without support */
.hero-claim {
max-width: 32ch;
text-wrap: balance;
}
@supports (text-wrap: balance) {
.hero-claim {
max-width: 24ch; /* balance handles the rest */
}
}
For content management systems it is also worth not leaving the choice between balance and pretty to the editor, but enforcing it through content type templates. A blog article template applies pretty automatically to every generated paragraph, while a landing page template applies balance to all headline components, regardless of what text an editor later enters.
8. Performance and reflow costs
Both balance and pretty incur additional computation cost compared to the standard break, because both algorithms evaluate several wrapping variants instead of just taking the first fitting one. For balance, this extra cost is bounded by the line limit and in practice not measurable for headings and short text blocks. For pretty the effect is even smaller, since only the trailing lines are considered.
The performance question becomes more relevant in highly dynamic layouts, for instance text blocks that change width in real time through user interaction, such as dragging a sidebar. Every width change triggers a new balancing pass. For most websites with static or responsive but not continuously changing layouts, this aspect is negligible, but it should be kept in mind for editor like interfaces with live resizing.
Measurements in real projects show that the difference between the standard break and balance during initial rendering of typical headings lies in the range of fractions of a millisecond, well below what a user could perceive. Only with hundreds of simultaneously balanced elements on a single page, for example in a very text heavy tile overview, does the effect accumulate into a measurable, though still small, total time.
A further aspect that is often overlooked in practice: both values only operate within the block element on which they are declared, and do not interact across element boundaries. A heading with balance and the directly following paragraph with pretty are computed completely independently of each other, there is no joint optimization across both blocks. This is usually desired in practice but should be kept in mind when debugging unusual wrapping results.
9. Use cases compared directly
The choice between balance and pretty is not a matter of taste, but depends directly on the element type and the expected text length. The following overview shows which value is the better choice for which use case.
| Element | Wrong choice | Recommended value | Reason |
|---|---|---|---|
| Hero heading | pretty | balance | Few lines, even distribution matters |
| Article paragraph | balance | pretty | Too many lines for balance's limit |
| Card title | no text-wrap | balance | Prevents a single word on line two |
| Image caption | no text-wrap | pretty | Prevents a lonely last word |
| Long blog text | balance | pretty | No line limit needed |
The clear rule is: balance for anything short and prominent, pretty for anything long and flowing. Respecting this boundary produces cleaner typography in both cases, without hitting balance's internal line limit or wasting pretty's finer effects on text that is too short.
For edge cases, such as a three line product description on a tile, a quick test in the browser developer tools is worthwhile: if the text with balance actually becomes more even without exceeding the internal line limit, balance is the better choice. If the result looks unchanged because the limit has already been reached, switching to pretty is advisable, since it works reliably even with more lines.
10. Summary
text-wrap: balance and text-wrap: pretty solve two different line breaking problems with different algorithms. balance evens out short text blocks like headings across all lines and is internally limited to a few lines. pretty specifically prevents single words at the end of long body text paragraphs, without a line limit and with less computational overhead. Correctly combining both values in the same project, balance for headings and pretty for body text, fully replaces manual <br> tags and JavaScript solutions.
Once this rule is anchored in the design system, every new page benefits automatically, without editors or developers having to make the decision again. That is exactly where the practical value of declarative text-wrap lies compared to earlier, imperative solutions.
Both values work as progressive enhancement without an @supports safeguard, because older browsers simply ignore the declaration and fall back to the standard break. For new projects it is worth including balance and pretty in a design system's base typography rules from the start, rather than adding them retroactively per component.
In the end the core message stays simple: two lines of CSS reliably replace what used to either go unsolved or require elaborate JavaScript libraries, a clear win in maintainability without compromising visual quality.
For teams migrating an existing design system, a step by step approach is recommended: first apply pretty globally to all body text elements, since the risk of unexpected layout shifts is minimal here, then add balance specifically to heading components while checking each one against the internal line limit. This approach minimizes surprises and makes the transition low risk in existing projects.
text-wrap: balance vs. pretty — the essentials at a glance
balance
For short, prominent blocks like headings. Evens out lines, internally limited to a few lines.
pretty
For long body text paragraphs. Prevents lonely last words, no line limit.
Combination
Apply balance to headings, pretty to body text in the same layout.
Fallback
Both values are progressive enhancement, no @supports strictly required.