← All writing
Craft · · 6 min

One word on the second line

On the 4 workarounds I'm not proud of, the 2 values that replaced them, and why it had to be 2 values and not 1.

CSS Typography

And it reads as a mistake even when nothing is broken.

A three-up card grid, headings of roughly the same length, all of them wrapping sensibly at every width I bothered to check. Then somewhere around 900px one card goes 5 words on the first line and then “surveys,” alone, down on the second. It looks wrong in a way the client will absolutely notice and won’t be able to name.

Things I have actually done about this

A non-breaking space typed between the last two words. Works! It’s also a line-breaking decision stored in the copy. So it’s correct at one width and wrong at every other one, it goes out in the RSS feed and the search snippet, and the first person to edit that heading in the CMS deletes it without ever knowing it was there. Which is the same fate as everything else you hide in the content. I’ve already written about what a CMS does to the decisions you leave lying around in it.

A <br> inside a media query. Same problem, plus now the markup is breakpoint-specific, plus some assistive tech announces a break in a sentence that doesn’t have one.

Asking the client to reword the heading. I have genuinely done this, more than once. I knew perfectly well at the time that changing what a business says about itself so it fits my grid is the tail wagging the dog 🥲

A JavaScript library that walked the DOM inserting non-breaking spaces. It ran after layout, so you could watch the reflow happen. It had to run again on every resize.

Four attempts to express a typographic preference through a mechanism that was never built to carry one. There are 2 values for it now, balance and pretty, they do genuinely different jobs, and between them they cover most of what those 4 hacks were reaching for.

Two problems, not one

It’s 2 values because a rag goes wrong in 2 unrelated ways. I’m not sure I’d ever separated those in my head before I went and read the spec.

In a short block, a heading or a caption or a button label, the failure is uneven lines. Six words and then one. A full line and then a stub. You want the lines to come out roughly the same length, even if the cost is pulling words off the first line to get there.

In a paragraph you want none of that. Balancing 15 lines would be expensive and would also look strange, since a paragraph’s whole job is to be a solid block with one ragged edge. There you want something much narrower, which is just that it shouldn’t finish on a single word sitting by itself.

Two different objectives, so two different values. One value doing both was never on the table.

Balancing act

typography.css
h1, h2, h3,
.card__title,
figcaption,
blockquote {
  text-wrap: balance;
}
CSS

The browser lays the block out, finds the narrowest width at which it still occupies the same number of lines, and uses that width instead. So the heading that broke six-and-one comes back four-and-three and the shape reads as deliberate.

It’s most obvious on centered text, where an uneven rag is a lot harder to ignore, and on anything inside a card or a narrow column, where there aren’t many break points to choose from in the first place.

The limitation worth knowing about is that implementations cap it at a handful of lines, 6 in the one I went and checked, because the layout work gets repeated per attempt and it isn’t free. Past the cap it silently does nothing at all. Which is the right call. It means “why won’t my paragraph balance” has a very ordinary answer.

Pretty please

typography.css
p, li {
  text-wrap: pretty;
}
CSS

This one leaves the body of the paragraph alone and works on the tail, so you don’t get the lone word on the final line and the rag over the last few lines comes out tidier. Much cheaper than balancing, and fine on body copy at any length, because it isn’t trying to reconsider the whole block.

Two engines have it, the third has it coming. And the degradation is that you get exactly the typography you have on the page today. So there’s nothing to feature-detect and nothing to guard.

It’s a hint, not a promise

You can still get a break you don’t like. A very long word, or a column narrow enough that there’s only one sane place to break, and the browser does its best with what it has. Both values improve the distribution. Neither one promises you a specific result, and if you go in expecting a guarantee you’ll be disappointed by a rag that’s merely better.

Neither of them fixes line length, either. A paragraph running to 140 characters a line is hard to read no matter how gracefully it ends, and the fix for that is still a max-width somewhere in the region of 60 to 75 characters. These polish typography that’s already good. They don’t stand in for it.

And don’t put balance on everything. It is very tempting to write it once on * and go do literally anything else. But it costs real layout work, it’s capped on long blocks anyway so most of that work gets thrown away, and applying it globally means paying for the attempt in every place it was never going to be used.

Nobody is going to notice

This is small. Nobody has ever looked at a site and remarked that the headings break nicely, and no client has ever put it in a brief.

It’s in the same drawer as the print stylesheet nobody asked for, which is to say invisible when it’s right, faintly embarrassing when it’s wrong, and one of a hundred details that add up to a page feeling considered without anyone being able to point at why. That drawer is my favorite part of this job, which I recognize is a slightly odd thing to admit.

Typesetters have been fussing over the rag for something like 500 years and doing it by hand the entire time, and my own contribution to that tradition was typing an invisible character into a client’s headline and hoping nobody ever touched it. It’s a declaration in a stylesheet now, which is where a decision about line breaking always belonged. It’s right at every width instead of at the one I happened to have open.

Read similar posts
2 min

text-wrap: balance and pretty

Two values that fix the two ugliest things typesetting does on the web, and the rule for which to use is entirely about how many lines you have.

2 min

word-break and overflow-wrap

Two properties that sound like synonyms, do different things, and get reached for in the wrong order roughly every time a long URL breaks out of a card.