CSS text-wrap: balanced headlines, no lonely words

2026-11-09来源 dev.to UXEnglish

This note has an interactive demo. Try it in the original

This Friday, 13 November 2026, text-wrap: balance becomes Baseline Widely available. Web.dev defines that status as 30 months after a feature works in every major engine, and webstatus.dev dates that moment to 13 May 2024, when Safari 17.5 shipped it. It's a good excuse to look at the two text-wrap values that fix the typography problems we've all shipped: headlines with one long line and one tiny one, and paragraphs that end with a single word hanging on its own.

The problem: the browser only looks one line ahead

By default, the browser wraps text greedily. It fills a line until the next word doesn't fit, breaks, and moves on, without looking at what that does to the following lines. That's fast, and for most text it's fine. But on a three-line headline, like the one in the demo, it often leaves "alone" by itself on the last line, and in a paragraph it creates a short last line that looks like a mistake.

Designers used to fix this by hand with <br>, &nbsp; between the last two words or a JavaScript library that measured the text. All of those break as soon as the width changes, the font loads late or someone edits the copy.

Two values, two jobs

text-wrap is a shorthand for text-wrap-mode (wrap or nowrap) and text-wrap-style. The interesting values are on the style side:

  • balance spreads the text so that every line has roughly the same number of characters. It's meant for short blocks: headlines, captions, pull quotes.
  • pretty keeps normal wrapping but lets the browser use a slower algorithm that favours better layout over speed. In practice, it's what avoids the lonely last word in a paragraph.

This is all the CSS the demo above uses on its "After" panel:

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

Play with the width slider (or press "Sweep") and watch the bars: each one is a real line, measured with a Range per word and getClientRects(). On the left, with plain wrap, at many widths the headline ends with a last line that is barely a fifth of the column, marked in orange as a "lonely word". On the right, balance evens the lines out, and the shortest line is usually two or three times longer. You can switch each element between wrap, balance and pretty to see what each value does on its own.

What balance doesn't do

balance changes where lines break, not how wide the box is. The Chrome docs point out that a balanced heading can leave empty space on the right, which looks odd inside a card with a border or a background. If that bothers you, set a max-inline-size on the heading.

It also has a line limit, because balancing is expensive. According to MDN, it only kicks in for blocks of six lines or fewer in Chromium and ten or fewer in Firefox. Beyond that, the text wraps as usual. That's why balance makes no sense on body copy: Chrome's own guide recommends using it selectively on headings and not on *.

What pretty does depends on the browser

The spec leaves the exact improvements to each browser, and the two engines that ship it really do different things:

  • Chrome added pretty in version 117. Its blog says it's focused on orphans: it avoids a single word on the last line, and adjusts earlier lines to make room.
  • Safari added it in version 26. The WebKit team says their implementation improves every line of the paragraph, not just the end: it evens out the ragged edge, avoids short lines and reduces hyphenation. The same post says Chromium only adjusts the last four lines.

On performance, MDN warns that pretty has a cost and recommends it for text where layout matters more than speed. The WebKit post is more relaxed: the number of elements doesn't matter, and you'd need paragraphs of hundreds or thousands of lines to notice anything.

Browser support and fallback

According to MDN's compatibility data, balance works in Chrome and Edge 114, Firefox 121 and Safari 17.5. pretty works in Chrome and Edge 117 and Safari 26, but not in Firefox yet.

The nice part is that you don't need a fallback. If a browser doesn't know the value, it ignores the declaration and the text keeps wrapping as always. Nothing breaks: it just looks slightly worse. If you want to know which case you're in, as the demo does to show its warning, it's one line:

const hasPretty = CSS.supports('text-wrap', 'pretty'); 

In Firefox, the demo detects that pretty isn't supported, says so, and its paragraph behaves like wrap, which is exactly what your users will see.

One small gotcha: if you use the longhand, the property is text-wrap-style: balance, not text-wrap-mode, which only accepts wrap and nowrap.

What to keep an eye on

  • pretty in Firefox: until it arrives, a third of the picture is missing, although the fallback costs nothing.
  • Chromium and the rest of the paragraph: if Chromium extends pretty beyond the last lines, as WebKit did, the result will look more alike across browsers.
  • avoid-short-last-line: it already appears in the text-wrap-style grammar on MDN, but MDN's compatibility data doesn't list it for any browser, so I'm not using it yet.

Sources

Originally published at richi.codes.

原文:https://www.a8q9.cn/en/article/css-text-wrap-balanced-headlines-no-lonely-words-3e7df8.html

相关文章