loke.dev
Header image for A Subtle Logic for the Balanced Headline

A Subtle Logic for the Balanced Headline

Stop fighting with manual line breaks and orphans; the text-wrap property finally brings algorithmic balance to your typography.

· 4 min read

We’ve all been there: you’ve crafted the perfect headline, but on a 1440px screen, it looks like a lopsided staircase. One long line followed by a lonely two-word straggler on the second. Your first instinct is probably to reach for a <br> tag or a non-breaking space (&nbsp;), but that’s a trap. As soon as that screen shrinks to a tablet, your manual break becomes a typographic car crash.

The text-wrap: balance property is the browser finally admitting that humans shouldn't be doing math to make titles look pretty.

The manual break is a lie

Historically, achieving a "balanced" look meant playing a dangerous game with viewport units or media queries. If you hard-coded a line break to prevent an orphan, you’d end up with something like this on mobile:

<!-- Don't do this anymore. Seriously. -->
<h1>
  The Future of Web <br> Design is Here
</h1>

On a small phone, that <br> might trigger after the second word, leaving a massive gap and making the title look broken. It's brittle. It's annoying to maintain. It makes me want to close my laptop and go for a walk.

Enter text-wrap: balance

The text-wrap property (specifically the balance value) hands the responsibility back to the browser's engine. When you apply it, the browser performs a quick calculation to equalize the length of the lines.

h1, h2, .balanced-text {
  text-wrap: balance;
  max-width: 800px; /* Essential for giving the algorithm room to work */
  margin-inline: auto;
  text-align: center;
}

Instead of just filling the first line until it hits the edge and dropping the rest to the next, the browser says, "Okay, if I have 40 characters total, I’ll give each of these two lines roughly 20."

It’s subtle, but it makes a massive difference in the visual "weight" of your headers.

Why can't we use it everywhere?

You might be tempted to throw text-wrap: balance on your entire <body> tag and call it a day. Don't do that.

The balancing algorithm is computationally expensive. To figure out the best split, the browser has to iterate through various permutations. Because of this performance hit, browsers currently limit the "balancing" effect to a small number of lines—usually around 4 to 6.

If you try to balance a 500-word blog post, the browser will likely ignore the property entirely to keep the page from stuttering. Keep it strictly for:
* Headlines (H1–H3)
* Blockquotes
* Short introductory "lede" paragraphs
* Tooltips

Solving the "Orphan" problem with pretty

While balance is for headlines, there’s a second value that is arguably more useful for body text: text-wrap: pretty.

Have you ever seen a paragraph where the very last line is just a single, lonely word? Typographers call that an "orphan" (or a widow, depending on which school of design you went to), and it’s an eyesore.

p {
  text-wrap: pretty;
}

Unlike balance, which tries to make all lines equal, pretty is much faster. It specifically looks at the end of a block of text. If it detects a single word on the last line, it moves one more word down from the penultimate line to keep it company. It’s a "look-ahead" algorithm that prioritizes the health of the final line.

A Real-World Comparison

Let’s look at how these behave in a standard CSS card component.

.card {
  width: 300px;
  padding: 1.5rem;
  border: 1px solid #ddd;
}

/* The Headline: We want it balanced */
.card-title {
  font-size: 1.5rem;
  text-wrap: balance; 
  line-height: 1.2;
}

/* The Description: We just want to avoid orphans */
.card-desc {
  font-size: 1rem;
  text-wrap: pretty;
  color: #666;
}

In the example above, text-wrap: balance ensures the title doesn't look top-heavy. Even if the title is "The Best Ever Tacos," the browser will likely split it as "The Best / Ever Tacos" instead of "The Best Ever / Tacos."

Meanwhile, text-wrap: pretty on the description ensures that if the last sentence ends with "...available now," the word "now" isn't sitting on a line by itself.

Browser Support and Progressive Enhancement

The beauty of text-wrap is that it’s the definition of progressive enhancement. It’s supported in Chrome, Edge, and Safari. Firefox is the main holdout at the time of writing, but here’s the thing: it doesn't matter.

If a browser doesn't support text-wrap: balance, the text just wraps normally (the "greedy" way). The layout doesn't break; it just looks slightly less polished. You don't need a polyfill, and you don't need a complex fallback.

/* If supported, it looks great. 
   If not, it's business as usual. */
h1 {
  text-wrap: balance;
}

The Verdict

We’ve spent a decade trying to fix typography with JavaScript hacks and weird CSS "ch" unit tricks. text-wrap: balance is the elegant, native solution we’ve been waiting for. It respects the flow of the web while giving us that bit of "print-quality" control we crave.

Go through your current project, find your .hero-title class, and add text-wrap: balance. Your users probably won't notice the change consciously, but their brains will thank you for the lack of visual clutter.