How to break long words using CSS @supports

Recently, I had an odd scenario where wrapping long text needed either word-wrap, overflow-wrap or word-break to achieve the same overflow pattern across different browsers. To arrive at a suitable solution I opted to use @supports to maintain control of the declarations.

What is @supports?

@supports is a feature query, whose associated block of statments only get triggered when the client (i.e. browser) supports the feature(s), as described on MDN. Here’s a simple example:

/*
 * Test if client supports display: grid 
 */
@supports (display: grid) {
  display: grid;
  float: none;
}

The example above is pretty self explanatory:
Process the enclosed block of declarations if the control declaration is know by the client.

The Problem – text that is too long for the width of its containing box

This is a common webpage layout hurdle, and one that completely breaks the page if not handled with due consideration. Take for example a scenario I’ve seen time and again: horizontal scroll on a mobile device, where the content overflowing to the right of the viewport is completly unstyled, as depicted below (NB: the site in the demo isn’t broken – we’re just demostrating the issue):

Toggle Demo

Overflowing text on mobile device
The perils of untamed text

Using @supports to handle long words

This is an ugly problem. And one that’s often addressed with a combination of hyphens(inc. prefixes) and word-break. Unfortunately, there are times when they don’t cut it. For example, when a hypen isn’t a desirable aethestic, or not all words want breaking.

What I was looking for was a way to break long words, but not hypenate them, and defintely don’t break words that can just fit on the next line. So, through trial and error, I found the following to work perfectly for our use-case, which only passes the relevant declarations to browsers that support them:

/*
 * Break long words
 * Only break words that are too long to fit on one line
 * Uses @supports
 */
h1, h2, h3, h4, article {
  /* doesn't recognise underscored_words on all browsers */
  word-wrap: break-word; 
}
@supports (overflow-wrap: break-word) and (not (word-break: break-word)) {
  /* doesn't recognise underscored_words on all browsers, use if word-break: break-word isn't supported */
  h1, h2, h3, h4, article {
      overflow-wrap: break-word;
  }
}
@supports (word-break: break-word) {
  /* use if supported */
  h1, h2, h3, h4, article {
      word-break: break-word;
  }
}

Conclusion

Using @supports is an elegant way to make us of the tools that fit each of the browsers we need to code for. Sometimes, more-often-than-not, we don’t need to use it. In the case above I could have just let the browser’s decide if they could or couldn’t understand the declarations, but the way I’ve structured it gives me confidence that I’ll get the desired outcomes from the declarations I’ve tested. Plus it gave me a reason to talk about @supports.