Better Line Breaks With CSS balance and pretty
A heading that leaves one short word on its last line can look awkward. Adding <br> fixes one width and creates a new problem at the next breakpoint.
CSS can now improve the wrap while keeping line breaks responsive.
View code
<label>Text width <input id="width" type="range" min="18" max="40" value="28"> <output id="value">28ch</output></label>
<div class="samples">
<section><h2>Normal wrapping</h2><p class="normal">Small details can make a website much easier to read and use every day.</p></section>
<section><h2>text-wrap: balance</h2><p class="balance">Small details can make a website much easier to read and use every day.</p></section>
<section><h2>text-wrap: pretty</h2><p class="pretty">Small details can make a website much easier to read and use every day.</p></section>
</div>
<p class="note">The difference depends on the width, font and browser. Some widths produce the same breaks.</p>button, select { padding: .35rem .6rem; border: 1px solid var(--clg); background: var(--cw); color: var(--cb); }
input[type="range"] { width: min(100%, 18rem); vertical-align: middle; }
h2, h3 { font-size: 1rem; }
.note { color: var(--clg); }
.samples { --width: 28ch; }
.samples section { margin-top: 1rem; }
.samples h2 { margin: 0 0 .4rem; }
.samples p { width: min(100%, var(--width)); margin: 0; border-inline-start: 2px solid var(--cl); padding-inline-start: .75rem; }
.normal { text-wrap: wrap; }
.balance { text-wrap: balance; }
.pretty { text-wrap: pretty; }const width = document.querySelector('#width');
width.addEventListener('input', () => {
document.querySelector('.samples').style.setProperty('--width', `${width.value}ch`);
document.querySelector('#value').value = `${width.value}ch`;
});Balance short headings
h1,
h2 {
text-wrap: balance;
}
The browser distributes text more evenly across available lines. This works best for short headings, not long article copy where balanced lines can become expensive or visually strange.
I normally combine it with a readable width:
h1 {
max-width: 20ch;
text-wrap: balance;
}
The width does most of the typographic work; balancing improves the final breaks.
pretty targets awkward paragraph breaks
.intro {
text-wrap: pretty;
}
pretty asks the browser to prefer nicer wrapping, including avoiding poor final lines where possible. It is not a reason to apply extra wrapping work to every paragraph on a long page.
The detailed behaviour and support are covered in MDN’s references for text-wrap and text-wrap-style.
The distinction I use is simple: balance for short headings with a few lines, pretty for selected introductions or pull quotes. Unsupported browsers fall back to normal wrapping, so both work well as progressive enhancement.
These properties are small improvements, not substitutes for sensible measure, font size, and copy length. Start with readable typography, then let the browser tidy the line breaks instead of freezing them in HTML.