CSS box-decoration-break: The Only Fix for Broken Multi-Line Text Highlights

CSS box-decoration-break: The Only Fix for Broken Multi-Line Text Highlights

You’ve seen it. You spend thirty minutes getting the padding, border-radius, and background color on a highlight span just right — it looks perfect in your preview at one line. Then you resize the browser, or a user with a slightly smaller screen loads the page, and the text wraps. Suddenly the highlight looks like two completely separate boxes stacked on top of each other with a hard edge in the middle, zero border-radius on the broken ends, and padding that only exists on the outside of the whole element, not on each line fragment. It’s not subtle. It looks broken because it is.

I’m Rohan Ratnayake, and I’ve spent the last 5 years as a front-end UI developer specializing in editorial and content-heavy web design — the kind of work where a highlight effect on a pull quote isn’t decoration, it’s a core part of the reading experience. I’ve watched junior developers chase this bug through display: inline-block, nested spans, JavaScript line-splitting hacks, and pseudo-element tricks that collapse the moment the font size changes. I did the same thing for the first two years of my career before I found the one CSS property that actually solves it at the source.

The fix is box-decoration-break. Most tutorials won’t cover it properly because most tutorials stop at background-color: yellow and call it a day. This one won’t.


Why Your Highlight Looks Wrong at Line Breaks

When a browser renders an inline element that wraps across multiple lines, it treats the whole element as one continuous box and then “slices” it where the line breaks. By default, the slice behavior — called slice — applies padding, border, and border-radius only to the outer edges of the entire element, not to each individual line fragment.

Here’s what that means visually:

Propertyslice (default)clone
Border-radiusOnly on first and last lineApplied to every line fragment
PaddingLeft/right only on outer edgesApplied to each line start and end
BackgroundContinuous, uninterrupted boxEach line gets its own background box
Box-shadowWraps entire multi-line elementApplied per line fragment

That table isn’t theoretical. If you set border-radius: 4px on a highlighted span and it wraps, you’ll see the radius on the far left of line one and the far right of line two — and nothing on the inner break edges. It looks like a rectangle with two corners shaved off in the wrong places.

ALSO READ:  How to Build a Pure CSS Typing Effect That Actually Works (No JavaScript Required)

What box-decoration-break Actually Does

The property has two values:

  • slice — the browser default. Decorations (padding, border, border-radius, box-shadow, background) are applied to the bounding box of the whole element before slicing at line breaks.
  • clone — every line fragment is treated as an independent box. It gets its own padding, its own border-radius, its own background rendering.

You use it like this:

.highlight {
  background-color: #FFE066;
  padding: 2px 6px;
  border-radius: 4px;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

The -webkit- prefix still matters in 2024. Safari requires it. Without it, your highlight will look fine in Chrome and Firefox and completely broken in Safari — which, depending on your audience, could be 20% of your users staring at a busted UI.


Building the Highlighter Effect Step by Step

The yellow marker effect you see on editorial sites — where it looks like someone physically dragged a highlighter pen across the text — relies on a few things working together. box-decoration-break: clone is the foundation, but it’s not the whole answer.

Getting the Base Markup Right

The highlight needs to be on an inline element, not a block element. A <span> is correct. A <div> or a <p> will not fragment across lines because block elements don’t behave that way.

<p>This sentence has a <span class="highlight">key phrase that might wrap onto the next line if the screen is narrow enough</span> to demonstrate the effect.</p>

The CSS That Actually Works

.highlight {
  background-color: #FFE066;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  padding: 0.1em 0.4em;
  border-radius: 0.2em;
  line-height: 1.6;
}

A few things worth explaining here:

  • padding: 0.1em 0.4em — using em values instead of px means the padding scales with the font size. If you use px, the highlight will look cramped on large headings and over-padded on small body text.
  • border-radius: 0.2em — same logic. This creates a consistent soft edge regardless of text size.
  • line-height: 1.6 — without adequate line-height, the highlight boxes from adjacent lines will touch or overlap. At 1.6, there’s breathing room between highlighted lines.

The Problem With box-shadow Highlights

Some developers swap background-color for box-shadow to get more control over the vertical position of the highlight (so it sits lower, like a real marker stroke). This works — but box-decoration-break: clone also applies the box-shadow to each fragment independently, so you need to be aware that overlapping shadows on tight line-heights will compound visually.

ALSO READ:  How to Add Text Outlines in CSS Without Breaking Your Layout (The text-shadow Method That Actually Works)

If you want a “real marker” look with the highlight sitting in the lower third of the text, this approach works well:

.highlight-marker {
  background-color: transparent;
  box-shadow: inset 0 -0.3em 0 0 rgba(255, 224, 0, 0.6);
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
  padding: 0 0.2em;
}

The inset box-shadow trick creates a bottom-aligned fill without touching the ascenders of letters like “h” or “d.” But it won’t work cleanly at line breaks without box-decoration-break: clone. Without it, the shadow only appears on the bottom of the final line.


Browser Support: What You Need to Know Before Shipping

box-decoration-break has solid support but it’s not universal without the prefix. Here’s the real picture:

Browserbox-decoration-break: clone supportRequires -webkit- prefix
Chrome 85+FullNo (but harmless to include)
Firefox 32+FullNo
Safari 14+FullYes
Edge 79+FullNo
Safari iOS 14+FullYes
Opera 71+FullNo

The MDN Web Docs page on box-decoration-break has the full compatibility matrix with version-by-version breakdowns. Always check it before assuming support — browser engine updates happen faster than most tutorials get updated.

The takeaway: always write both the -webkit- prefixed version and the standard version. It costs you one extra line and saves you from a Safari-specific bug report.


A Real Scenario Where This Mattered

Last year I was building an online magazine template — long-form articles, lots of inline callouts and emphasized phrases. The client wanted a “hand-highlighted” look on editorial pull quotes inside body paragraphs. I delivered the first version with background-color and standard padding. Looked fine on my 1440px monitor.

The client came back two days later with a screenshot taken on their iPhone SE. The highlighted phrase had wrapped onto two lines and the inner edges looked like a hard rectangular cut — no radius, no padding, just a flat break. I’d shipped it without testing at 375px viewport width. Cost me an extra round of revisions that took about 4 hours to fix, document, and re-QA.

That was the day I started testing highlight effects on a narrow viewport before anything else.


When Padding Creates Line-Height Problems

One specific failure I’ve seen repeatedly: developers set generous vertical padding on highlighted spans — something like padding: 6px 10px — and then wonder why the line spacing looks inconsistent between highlighted and non-highlighted lines.

ALSO READ:  CSS Gradient Text That Actually Looks Good: A Developer's Guide to Background-Clip

The issue is that inline elements with padding don’t push adjacent lines apart in the same way block elements do. The padding overlaps with the line-height of surrounding lines. The result is highlighted text lines that sit closer together than non-highlighted ones, or text that visually collides with the line above.

The fix is to set line-height on the parent paragraph, not on the span:

p {
  line-height: 1.8;
}

.highlight {
  background-color: #FFE066;
  padding: 0.1em 0.35em;
  border-radius: 0.2em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

When the line-height is generous enough at the paragraph level, vertical padding on the span has room to breathe without creating visual collisions. The exact value depends on your font and font-size, but 1.7 to 1.9 is a reliable range for body text with highlight spans.


Highlight Styles You Can Actually Use

Here are four distinct highlight variations, each using box-decoration-break: clone as the base:

StyleEffectKey CSS
Classic markerYellow fill, rounded endsbackground: #FFE066; border-radius: 0.2em
Underline washPartial bottom fillbox-shadow: inset 0 -0.35em 0 rgba(255,200,0,0.5)
Bold highlightStronger color, slight text contrastbackground: #FFCE00; color: #1a1a1a
Pastel softSubtle, readable on dense textbackground: rgba(255,230,100,0.4)

All four require -webkit-box-decoration-break: clone and box-decoration-break: clone to render correctly at line breaks. The underlying structure is identical — only the visual treatment changes.


Accessibility: Don’t Highlight Just for Style

If you’re using highlight spans to call out important information, screen readers won’t communicate that a <span class="highlight"> has special meaning. The visual cue is invisible to assistive technology.

If the highlight is purely decorative, that’s fine — no changes needed. But if the highlight is meant to signal “this is important,” consider pairing it with a semantic element or ARIA attribute:

<span class="highlight" aria-label="key point">your highlighted text</span>

Or, if the highlighted phrase is genuinely critical information, wrapping it in <strong> or <mark> gives it semantic weight. The <mark> element in particular is defined in the HTML spec as text marked for reference or notation — which is exactly what a highlight represents. You can style <mark> with the same box-decoration-break technique and get both visual and semantic correctness in one element.


Three Questions That Come Up Every Time

Does box-decoration-break work on block-level elements? No. The property only has a visual effect on inline elements or elements with display: inline or display: inline-block. On block-level elements, there’s no fragmentation across lines, so the property does nothing meaningful.

Why does my highlight look different in Safari even with the -webkit- prefix? Safari renders background-color with slightly different anti-aliasing on rounded corners. If the corners look sharper in Safari than in Chrome, reduce your border-radius value slightly — Safari’s rendering engine handles sub-pixel radii differently. Values below 0.15em sometimes render as flat corners in Safari.

Can I animate a highlight revealing effect with this property? Yes. You can animate a background-size from 0% 100% to 100% 100% on a background-image: linear-gradient() for a left-to-right reveal animation. box-decoration-break: clone applies per fragment, so on multi-line text each line reveals independently from left to right — which actually looks intentional and clean. The animation needs to run with background-repeat: no-repeat and background-position: left center to work correctly.


The Line That Ties It Together

The background-color on its own will never give you a clean multi-line highlight — box-decoration-break: clone is the property that turns a broken box into a proper fragment-aware highlight.

Test every highlight style at a 375px viewport before shipping. Add the -webkit- prefix every time, no exceptions. Use <mark> if the highlighted content has semantic meaning, not just a <span>. And set your line-height on the parent element — not the span — to avoid the spacing collision that trips up nearly every developer the first time they add vertical padding to an inline highlight.