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

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:

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

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.