An end to typographic widows on the web

Currently shipping in Chrome Canary, and thus soon to be in Blink-based browsers including Edge, is a relatively new CSS declaration which promises to virtually end typographic widows.

The text-wrap:balance declaration in CSS Text Module Level 4 says that line breaks should be chosen to balance out the line lengths in a block of text. How exactly that is done is ‘UA-defined’, in other words it’s determined by the rendering engine rather than any specific rules or guidelines set in the CSS specifications. This is how today’s version of Chrome Canary balances out one of the longer headings in this blog:

A screenshot showing a long heading with the final word dropped to the sewcond line as a widow
Default text wrapping
A screenshot showing the same long heading with the text split evenly over two lines
‘Balanced’ text wrapping

What this is not is control over widows and orphans. My previous examples show how the text balancing algorithm in Chrome Canary does indeed prevent a widow (the single word dropped down), and that’s a highly likely outcome. But you have to remember that the balancing job shortens the lines, so this isn’t an approach you would take to prevent widows at the end of paragraphs. In fact Canary limits balancing to 4 lines (the spec itself recommends 10 or fewer). The CSS spec itself makes the application clear:

the balance value is intended for titles and captions, where equal length lines of text tend to be preferred

With that in mind, this is the rule I’ve applied to this blog, and I’d say could end up in most people’s default reset:

h1, h2, h3, h4, h5, h6, caption, figcaption {

Balancing left-aligned headings is not always preferable. I would love to have a value for text-wrap whose sole purpose is to prevent widows, without any other formatting involved. One could borrow from the widows property of the Fragmentation Module:

text-wrap: 2 widows  /* maybe one day */

Where 2 in this case specifies the minimum number of words allowed on the final line of a text block. There would have to be slightly more to it than this, in particular a single word should be allowed if the final two words together would be too long to fit inside the text block.

Another value in the specification is text-wrap:pretty. If it’s ever implemented, this might – as an outcome – reduce widows and orphans in running text. For decades there have been sophisticated algorithms for wrapping text across multiple lines. For performance purposes, browsers use the most basic approach, the so-called first-fit/greedy algorithm, which takes one line at a time, wrapping if it’s too long, and moving on to the next. In typographers’ eyes this gives sub-optimal results, and is one of the reasons text justification is so awful on the web.

Better algorithms, such as Knuth-Plass, take into account entire paragraphs and achieve a more nuanced approach to text wrapping by reducing and increasing spacing between words. The spec says that as optimal results often take more time, pretty is offered as an opt-in to take more time for better results. The pretty value is intended for body text, where the last line is expected to be a bit shorter than the average line. [… The browser] should bias for better layout over speed, and is expected to consider multiple lines, when making break decisions.

Algorithms such as Knuth-Plass won’t necessarily eliminate widows and orphans, but might go some way to doing so. The reluctance to using such approaches is understandable, however, as they can be extremely demanding: the processing requirements increase quadratically with the paragraph length. That said, a value such as pretty gives the option to choose different text wrapping procedures depending on conditions (resident processing power, length of text, etc). One day perhaps. Meanwhile I’d settle for direct control over widows and orphans in text blocks.