Multi-line Padded Text with the CSS box-decoration-break Property

A zoomed in and skewed view of inline text wrapping to multiple lines, with a teal background colour set only against the lines of text, with gaps in between the lines.

I love stumbling upon CSS properties in time of great need. Recently, I was working on a personal project, and I wanted to have multi-line highlighted text. My requirements were pretty simple from a design point of view:

  1. Text should be highlighted, i.e. have a background colour
  2. Highlights should only cover areas where there is text
  3. Each line should have a little left and right padding so that the text isn’t flush against the highlight box

My desired HTML was something like this:

Code language: HTML

<span>Hello, this is a long string of text that spills onto many lines</span>

And the desired output something like this:

A screenshot of some inline text wrapping to new lines. The text has a background colour and horizontal padding, which is duplicated at the start and end of each line.

If I used it as is, the output would look something like this:

A screenshot of some inline text wrapping to new lines. The text has a background colour and horizontal padding, but only the start of the first line and the end of the last one has horizontal padding applied, while the rest sit flush with the left and right of the content box.

So, how can we solve this? Luckily, CSS has thrown us a piece of candy in the box-decoration-break property. Let’s take a look.

[…]

Here’s an excerpt from the MDN:

The box-decoration-break CSS property specifies how the background, padding, border, border-image, box-shadow, margin and clip of an element is applied when the box for the element is fragmented. Fragmentation occurs when an inline box wraps onto multiple lines…

Basically, this property is giving us a bit more granularity in how an inline element gets rendered. By default, it’s set to slice, which means that it treats the inline box as if it weren’t fragmented at all. I like to think of it like this. Imagine that we took that multi-line inline element, stretched it out onto one line, applied the styling, sliced it into pieces, then moved each piece back to a new line. The result would be that the properties mentioned above would act on the entire box of the element, rather than each of its parts.

However, there is a second option for us, and that is:

Code language: CSS

box-decoration-break: clone;

When we set the property to clone, we can imagine a similar scenario as above, except one important thing. This time, let’s imagine that all the styles get applied after the element gets fragmented and distributed on multiple lines. In other words, paddings, borders, etc would be applied to each fragment almost as if they were separate elements.

That’s pretty awesome, and with one simple property, we’ve unleashed a ton of possibilities! Here’s a CodePen link with various demos for you to play around with.