All Articles

Wrapping and Truncating Overflowing Text with CSS

Image from Unsplash by Christian Chen
Image from Unsplash by Christian Chen

Recently, I’ve been struggling to understand how CSS properties typically come together to handle the wrapping and truncating of text items. My confusion stems from a number of implicit behaviours and the fact that some properties are able to override (or nullify) the values of others.

Quirky Properties

overflow-wrap: break-word and word-break: break-word, for instance, boggle my mind a bit. Besides the way they are named, both property-value pairs lead to very similar behaviours, but the properties themselves aren’t synonymous with each other.

overflow-wrap: anywhere can be thought of as a variant of overflow-wrap: break-word (as we’ll soon see below) while word-break: break-all is very different from word-break: break-word.

It helps to think of overflow-wrap as only applying to words that will overflow even when granted a full line to themselves. word-break, on the other hand, applies to words in a more general sense.

Other less significant examples would be text-overflow: ellipsis, which implicitly requires you to set overflow: hidden.

To be fair, implicit requirements are common in CSS (think about how layout properties are defined –– grid-template-rows requires display: grid and flex-flow requires display: flex). That said, developers working around text-specific quirks might find themselves hitting roadblocks every now and then if they’re not already familiar with the relationships between properties.

A Linear Approach

I’ve found it useful to think about text wrapping in a top-down manner. We start by evaluating the text body as single chunk and then gradually narrow our considerations down to “atomic” word / character components.

In particular, the following order of considerations make the most sense to me:

  1. text-align: How do we want the text to be aligned?
  2. text-overflow: How do we want overflowing text to be cut off?
  3. white-space: How do we want the spaces between words (and groups of words) to be handled?
  4. overflow-wrap: For words that extend beyond a single line, how should we break them?
  5. word-break: For words in general, do we allow them to be broken? How should we break them?
  6. hyphens: Do we want to break words with hyphens?

Check out this Storybook-inspired sandbox I’ve made which contains a text component supporting various toggleable values for each of the items in the above list. I’ve made this so that I wouldn’t be fussing around with these CSS properties as often in the future –– hopefully it’ll help you too!

Some interesting points to note:

  • hyphens: auto implicitly overrides word-break: normal. It tells the browser that we’re okay with breaking all words at overflow thresholds and we’d like to hyphenate these breakpoints.
  • Compared to hyphens: auto, word-break: break-all just does the first thing (telling the browser that words can be broken at any character when they hit the overflow threshold), but doesn’t bother with the second (i.e. the value of hyphens gets ignored).
  • If, like me, you’ve gotten the impression from this CSS Tricks article that text-overflow: ellipsis is only applied when white-space: nowrap is used, then you should know that that’s not entirely accurate.

    • text-overflow: ellipsis works fine with other options, including white-space: pre and white-space: pre-wrap.
  • overflow-wrap: anywhere is almost the same as overflow-wrap: break-word –– except that it allows the message container to be shrunken down to its minimum width if width: min-content is applied.