Part of the jedee wiki — pages written by an AI (Claude Code), supervised by Johan.
Text wrapping
A widow (typography’s term, loosely used) is a very short last line — usually one lone word — at the end of a paragraph or, most visibly, a heading. For most of the web’s history there was no CSS for this; the standard fix was JavaScript that swapped the last space for a (the approach in css-tricks’ 2013 article). Two values of the CSS text-wrap property now solve it natively:
h1 { text-wrap: balance; } /* even line lengths — headings, short blocks */
p { text-wrap: pretty; } /* better paragraph endings — running text */balancedistributes words so every line of the block is roughly the same length. Browsers cap it at a handful of lines (~6–10), so it is for headings, pull quotes, and captions — not paragraphs. Especially good for centered headings.prettyoptimizes where lines break with particular attention to the end of the block, preventing the lone last word. WebKit’s implementation goes further and evaluates the whole paragraph (their 2025 write-up); Chromium’s focuses on the last few lines. Use it on body copy.
Both, rendered in the site’s own faces at the same measure. Each pair is one string set twice; the only thing that differs between the columns is the property.

balance on a heading. Greedy wrapping strands Machine; balance evens the three lines instead.
pretty on running text. Greedy strands entity.; pretty pulls a word down onto the last line, at the same line count.⚠ A comparison like this is only worth anything if both columns are exactly the same width. The first version of the specimen gave the right-hand column 24px of extra padding, which produced a confident-looking difference that was entirely the narrower measure — with the widths equalized, the two columns rendered identically. The pair widths above are swept rather than chosen: 300px is where these two strings actually diverge in Chrome 151, and changing the text means sweeping again. The mockup is src/wiki/_sources/text-wrapping.html; npm run mockups re-shoots it.
Age note on the source. The raw clip below dates from 2024-04, when balance was everywhere except Safari and pretty existed only in Chrome and Opera. Those caveats are the article’s main hedge and are obsolete: balance finished landing across the major browsers during 2024, pretty during 2025 (caniuse). Both are safe to ship unconditionally — where unsupported, text simply wraps the old greedy way, which is the state you were in anyway.
In jedee
Both values are shipped, at four places in the cascade:
global/base/reset.css— the broad defaults, in theresetlayer:* { text-wrap: pretty }andh1, h2, h3, h4 { text-wrap: balance }. This is the whole site’s baseline.global/blocks/prose.css:39—.prose :is(p, li, dl, blockquote)repeatstext-wrap: prettyalongside the60chmeasure. Redundant with the reset in effect, but it keeps the prose block’s typographic decisions self-contained.local/post.css:9—.intro(the lede under a post title) getstext-wrap: balance: a short, display-adjacent block, so it takes the heading treatment rather than the paragraph one.global/blocks/breadcrumb.css:68— the gotcha. The current-page crumb must stay on one line, but the global* { text-wrap: pretty }reset re-enables wrapping even against an explicitwhite-space: nowrap. The block clamps with-webkit-line-clamp: 1instead, which wins wherenowraploses. Any future single-line truncation on this site has the same fight ahead of it — the reset’s universal selector reaches everything.
EE stock vs jedee: the reset and prose.css declarations are Eleventy Excellent’s stock typography. jedee’s own additions are the .intro balance and the breadcrumb line-clamp workaround.
Related: Microformats — the other page where a universal-selector reset interacts with a specific block in a non-obvious way (there margin: 0, here text-wrap).
Raw source: src/_raw/Prevent Widows in Post Titles with CSS.md (Josh Crain, 2024-04-24) — the wiki’s first external clip.