If you're fine using JavaScript, the Adopt-Words library seems to do the job.
https://www.cssscript.com/prevent-orphans-adopt-words/
It's under 2KB in size, though I haven't tested the runtime performance for large pages with a lot of text. By default it doesn't apply itself to the whole page: you specify what you want it to run on. So
AdoptWords.init('.example *', {
// options here
})
would only prevent orphan words on elements with the class example
. You could probably apply it to all p
, span
or whatever tags, but might incur a harder performance penalty depending on the number of elements affected.
It's MIT licensed. Even when you prettify the code it's only 56 lines, so it's easy to audit.
Hopefully in the future you can just use Kelvyn's answer, but as of early 2024 that's Chromium only. Tim and Alex's comments would add you Firefox support for blocks of text spanning a limited number of lines (six or less for Chromium and ten or less for Firefox), but you'd still miss out on Safari, which might be an issue if many of your users use iOS. It's very well possible that by next year you might be able to use one or both of their answers though.
Until then, I think the Adopt-Words library is probably the best solution. As squarecandy pointed out, the issue with adding
or span
tags in the other answers is that
If you automated this, it could break mobile layouts if the last two words are very long. If you don't automate it, it's difficult to train non-technical editors how to implement it correctly.
I'd also add that if you don't automate it, it becomes even more of a headache once you deal with translations for your page. I agree with squarecandy that those answers are very useful in some situations (e.g. if you need to make a change in a pinch or just on one particular page) but I think Adopt-Words might be the cleanest solution for a sitewide approach: you don't have to adjust your HTML at all beyond adding something like
<script src="adopt-words.bundle.js"></script>
<script>
AdoptWords.init('.example *', {
// options here
})
</script>
and if the user doesn't have JavaScript enabled, it should still fallback gracefully.
between the last two words – Dazeorphan-words: avoid;
would be so much more useful thanhyphens: auto;
to me at least. And seems like it would be way easier to implement. Sadly it does not exist at the moment. – Izaaktext-wrap: balance
– Anabranch