How to apply padding to multiple lines in CSS

By

Learn how to apply padding to every line of wrapped text in CSS with box-decoration-break: clone, plus the -webkit- prefix that Safari needs to render it right.

~~~

To apply padding to every line of wrapped text in CSS, set box-decoration-break: clone on the inline element. I found this out while re-designing some aspect of this blog, when I had the need to add some padding to each line of each blog post title.

I had this HTML:

<h1 class="post-title">
  <span>{{ .Title }}</span>
</h1>

I added this CSS:

.post-title span {
  padding: 0px 30px;
  background-color: rgb(254,207,12);
}

and it worked, it added a 30px padding at the left and right side of the article title, as you can see thanks to the yellow background:

Single-line title with yellow background and 30px padding on left and right sides

But with a longer title, and the text flowing to a new line, I experienced a problem because the padding was not applied at the end of each line:

Multi-line title showing missing padding at line breaks - no padding before A on second line

See? There’s no padding before the A letter in the second line, and after the semicolon on the first line.

To fix that, I used this CSS property called box-decoration-break with the value clone, and its -webkit- prefixed version for Safari:

-webkit-box-decoration-break: clone;
box-decoration-break: clone;

Then it worked fine, across all browsers:

Fixed multi-line title with proper padding applied to both lines using box-decoration-break clone

Why does this happen?

When inline text wraps, the browser splits its box into fragments, one per line.

By default, box-decoration-break is set to slice. The browser decorates the fragments as if they were still one continuous box, sliced at the line breaks. Padding, border and background only show at the very start and the very end.

With clone, each fragment is treated as a separate box. Every line gets its own padding and its own background, which is exactly what I wanted here.

The property also controls how boxes break across columns and pages, so it’s useful in multi-column layouts and print styles too.

One thing to watch out for

The property works on the fragments of an inline box. The span in my title is inline by default, so the text can break into fragments across lines.

If you set that span to display: inline-block or display: block, the fix stops working. The element becomes a single box that wraps as a whole, there are no fragments anymore, and box-decoration-break has nothing to clone. Keep the element inline.

And remember to keep both the prefixed and unprefixed lines, so Safari renders it correctly too.

Tagged: CSS · All topics
~~~

Related posts about css: