Dec 16

CSS text-wrap

By Eric Meyer

In print typography, a lot of attention is paid to line-breaking and text wrapping (among many other things).  In web typography, where we have no guarantee of line length, display area, or even font face, we’ve traditionally either ignored those things or hacked like mad scientists.  It’s all part of the Dao of web design, even if that does sometimes mean weirdly balanced text or hanging single words (known as “runts”, at least sometimes).

But now, thanks to the shorthand property text-wrap — I’ll break it apart into the longhand properties later — we can exert… well, some influence.  Plus we can do things that we used to rely on white-space to do.  For example, we can prevent text wrapping!

Figure 1. Text wrapping normally, and not wrapping at all.
Figure 1. Text wrapping normally, and not wrapping at all.

nowrap, as its name implies, prevents line-wrapping.  You can still use white-space: nowrap if that’s what your fingers’ muscle memory has programmed, so don’t worry about that going away.

Beyond that, text-wrap offers two very welcome new values.  First up, you can have the browser balance your element’s line lengths.  Compare the following example of text-wrap: balance to the text-wrap: wrap shown in Figure 1.

Figure 2. Balanced text wrapping.
Figure 2. Balanced text wrapping.

There are no line-breaks or other extra bits in the HTML content.  Instead, the browser has looked at the element’s layout size and its content, and then shifted the line breaks around so that the individual lines of text are as close as possible to the same length.

You might think this would be computationally expensive, and you’re right, it is.  That’s the reason some browser engines limit the number of lines of text to which this can be applied: six for Chromium, and nine for Gecko.  WebKit, on the other hand, either doesn’t impose a limit, or has a limit higher than my testing could find (I went up to 25 lines).

Still, it’s really an effect to be used on headings, pull quotes, and other elements that will have enough content to run more than one line, but not so much content that they go past around five lines.

There’s also a way to have “normal” line wrapping while avoiding runts: text-wrap: pretty.  Here’s a comparison of the default behavior to the “pretty” version.

Figure 3. Preventing last-line loners with pretty wrapping.
Figure 3. Preventing last-line loners with pretty wrapping.

Here, the only line balancing is to avoid having the last line of text in the element have just one word.  You might have faked this in the past by replacing the last space in the element’s content with an  .  Now, the CSS will just do it for you, at least in Chromium browsers; support has yet to land in WebKit and Gecko.

Be careful, though: just calling the wrapping pretty does not guarantee pretty results, nor does it guarantee that you’ll never leave a lone word hanging at the end of an element.  Long words near the end of the content are a quick way to make things weird, as shown in Figure 4.

Figure 4. Some limits of pretty wrapping.
Figure 4. Some limits of pretty wrapping.

I would say the first example is better than the second, but either way, these are what pretty yielded.  It’s no worse than plain old wrap behavior, but it’s not really any better either.

It should also be noted that pretty could do a lot more in the future.  The current-as-of-this-writing draft of the specification says that beyond just avoiding runts:

The precise set of improvements is user agent dependent, and may include things such as: reducing the variation in length between lines; avoiding typographic rivers; prioritizing different classes of soft wrap opportunities, hyphenation opportunities, or justification opportunities; avoiding hyphenation on too many consecutive lines…

That’s the entire sentence — the ellipsis at the end there is part of it.  So this is a value that could lead to rendering changes over time, should browser engines choose to do more.

As I said up top, text-wrap is actually a shorthand property that encompasses the properties text-wrap-mode and text-wrap-style.  The values wrap and nowrap come from text-wrap-mode, whereas balance and pretty come from text-wrap-style.  The latter also has a value called stable, which is defined to keep lines before the input cursor from re-flowing when the content is editable and being edited, but I couldn’t find any difference between stable and wrap behavior when I tested it.

So there you have it: text wrapping, all wrapped up for the holidays!  Whether you use it to prevent line-wrapping or make line lengths more consistent in headlines, text-wrap and its longhands give us some welcome new options in text layout.

Eric Meyer

Eric Meyer

CSS guy, author, speaker, Developer Advocate at Igalia.

Eric selected Rebecca’s Gift for an honorary donation of $50

Rebecca’s Gift

The money raised by Rebecca’s Fund will be added to the St. Baldrick’s efforts to fund promising research in the prevention of tumor reemergence.