Widows, Orphans & Rivers: Microtypography
Define widows, orphans, and rivers. Modern CSS fixes: text-wrap: balance for headings, text-wrap: pretty for paragraphs, hanging-punctuation, non-breaking spaces.
Widows, Orphans & Rivers: Microtypography
What Microtypography Addresses
If macro typography is about hierarchy, measure, and scale — the large architecture of a text — microtypography is about the quality of the individual line: the texture of a paragraph, the behavior of line breaks, the spacing of specific character pairs. It is the difference between text that merely functions and text that reads with ease and intention.
The three problems this article addresses — widows, orphans, and rivers — are the most common microtypographic defects in digital typography. Until recently, they were difficult to address in CSS without JavaScript. Modern CSS has changed that.
Widows and Orphans
These terms cause consistent confusion because they are used inconsistently across different fields. Here are the typographic definitions:
Orphan: The first line of a paragraph stranded at the bottom of a column or page, with the rest of the paragraph on the next column or page. An orphan is separated from its body.
Widow: A short final line of a paragraph — typically a single word or very short phrase — left alone at the end of a paragraph. A widow is stranded at the end.
Some print style guides also use widow to describe the last line of a paragraph stranded at the top of a column. Regardless of the specific definition, the general problem is the same: isolated lines that break the visual rhythm of a text block.
CSS Solutions
For column and page breaks, CSS provides orphans and widows properties that have been in the specification for years (primarily for print stylesheets):
@media print {
p {
orphans: 3; /* Minimum lines at bottom of column */
widows: 3; /* Minimum lines at top of column */
}
}
Screen support for these properties is inconsistent and they primarily affect multi-column or paged contexts. For single-column web reading, the more useful approach is text-wrap: pretty.
text-wrap: balance and text-wrap: pretty
CSS text-wrap is now available in all major browsers (Chrome 114+, Firefox 121+, Safari 17.4+). It has two values that address different problems:
text-wrap: balance for headings
text-wrap: balance distributes text across lines as evenly as possible, preventing the common case where a heading breaks so that the last line contains only one or two words:
/* Without balance: "Introducing Our New\nDesign System For\nMobile" */
/* With balance: "Introducing Our\nNew Design System\nFor Mobile" */
h1, h2, h3, h4, .card-title, .hero-headline {
text-wrap: balance;
}
text-wrap: balance is designed for short text (headings, pull quotes, captions). The browser algorithm is computationally expensive and the property is intentionally limited to elements with six or fewer lines — do not apply it to paragraphs.
text-wrap: pretty for paragraphs
text-wrap: pretty is designed for paragraph text. It prioritizes avoiding widows (lonely last words on a final line) and rivers, with special attention to the last few lines of a paragraph:
p, li, blockquote {
text-wrap: pretty;
}
text-wrap: pretty is less aggressive than balance — it accepts slightly uneven line lengths to avoid specific microtypographic problems. It is the right default for body text.
/* Recommended defaults */
h1, h2, h3, h4, h5, h6,
.card-heading,
.pull-quote {
text-wrap: balance;
}
p, li, dd, blockquote, figcaption {
text-wrap: pretty;
}
Rivers
Rivers are visual channels of white space that run through a justified text block, formed by the accidental alignment of word spaces across multiple consecutive lines. They are the result of the spaces-between-words in one line lining up with spaces in the lines above and below — the eye perceives a vertical or diagonal channel of space threading through the text.
Rivers are primarily a problem in narrow columns with full justification. The browser's word-spacing adjustments to achieve justification create spaces large enough to align visually.
Preventing Rivers
The most effective prevention: avoid full justification in narrow columns. Use text-align: left (flush left, ragged right) for web body text at column widths below 50–55ch. The ragged right edge is typically preferable to the uneven spacing that full justification produces in CSS without high-quality hyphenation.
If you must justify, enable automatic hyphenation to reduce word-space variation:
.justified-column {
text-align: justify;
hyphens: auto;
hyphenate-limit-chars: 6 3 3; /* min word length, chars before break, after break */
hyphenate-limit-lines: 2; /* max consecutive hyphenated lines */
}
hanging-punctuation
Hanging punctuation moves opening quotation marks, em dashes, and similar characters into the margin so that the left edge of a text block is optically aligned with the first letter, not the punctuation mark:
/* Hang punctuation into the margin */
p, blockquote {
hanging-punctuation: first last;
}
hanging-punctuation is currently supported in Safari only as of 2026. For other browsers, it is a progressive enhancement — the text reads correctly without it, but with it the optical alignment is more refined. Apply it and accept that some users will see slightly different text alignment.
Non-Breaking Spaces
A non-breaking space ( in HTML, \u00A0 in JavaScript) prevents a line break at that position. This is useful for:
- Preventing a two-character preposition from being stranded at the end of a line ("a"), especially in headings
- Keeping a number and its unit together ("32 px", "100 %")
- Preventing line breaks within proper names ("Dr. Bringhurst")
<!-- Keep units together -->
<p>The optimal measure is 65 ch.</p>
<!-- Prevent single-character word at line end in heading -->
<h2>Typography Is <span style="white-space: nowrap">a Craft</span></h2>
These are manual interventions, not systematic rules — use them when a specific break is problematic, not as a blanket treatment.
Key Takeaways
- Widow: a short final line of a paragraph; orphan: a paragraph's first line stranded at the bottom of a column
text-wrap: balanceevenly distributes heading text across lines — use on all headingstext-wrap: prettyreduces widows and rivers in paragraph text — use on all body copy- Rivers are caused by full justification in narrow columns; prevent with flush-left alignment or
hyphens: auto hanging-punctuationis a Safari-only progressive enhancement that improves optical left-edge alignment- Non-breaking spaces manually prevent unwanted breaks around short prepositions, numbers-with-units, and proper names