Preventing too-short final lines of text blocks

At the end of my previous post heralding an end to typographic widows on the web I wrote that I’d settle for direct control over widows and orphans in text blocks. It turns out not to be quite as a simple as one might think. Over the years, there’s been multiple discussions on the topic within the CSS Working Group (CSSWG). Following my post, I talked at length with other designers at Clearleft – in particular James Gilyead of Utopia.fyi fame – and it was surprisingly difficult to come to a definitive conclusion, particularly around the exceptions.

Put simply, one doesn't want a solitary word (a widow) on the final line of a block. But the tricky thing to answer is: what's the effect of bringing down a word from the previous line in order to address that? If you were fixing this manually there might be a ripple effect back up the paragraph until the best overall text shape is achieved. I doubt that's something a browser could afford to do, given the (understandable) reluctance to implement any justification routines beyond the crudest greedy method.

Bit by bit, the CSSWG seems to have been converging on a potential solution. In the current draft of the CSS Text Module Level 4, there is mention of Last Line Minimum Length, which raises an Issue as follows:

Issue is about requiring a minimum length for lines. Common measures seem to be: at least as long as the text-indent; at least X characters; percentage-based. […] People have requested word-based limits, but since this is really dependent on the length of the word, character-based is better.

Amelia Bellamy-Royds took the Last Line Minimum Length idea and proposed a solution with a new min-last-line property. Her proposed property would specify a minimum length for the final line, and a minimum length for the penultimate line once you’d dropped a word or more down to address the short final line.

This seemed like a pretty smart approach. Inspired by Amelia’s idea and my conversation with James, the proposal I’ve come to is conceptually similar to the hyphenate-char-limits property. Set a minimum character length for the final line along with a maximum number of characters to bring down from the previous line:

min-last-line: 12 6

Where 12 is the minimum line length in characters, and 6 is the maximum number of characters that can be brought down from the previous line to make that so. If the 6 is omitted, it would assumed to be equal to the 12.

It might be useful to some people for the same approach to be expressed as percentages of box width instead:

min-last-line: 20% 10%

Where 20% is the minimum length of the final line in terms of percentage of box width, and 10% is the maximum length that can be removed from the previous line.

There’s no reason I can think of why these values couldn’t be mixed:

min-last-line: 20% 8

Meaning the last line shouldn’t be shorter than 20% of the block width, but you shouldn’t bring down more than 8 characters to achieve that.

I've put together a very rough-and-ready proof of concept here.

The idea is to have something to test out the concept of a minimum final line length and maximum amount of text that can be brought down from the line above to address that. Please feel free to have a play, copy, adapt and generally improve. Your comments are very welcome, preferably in the CSSWG issue thread.