demo · v134

Overlapping highlights

The motivating use case was tooling — spell-checkers, grammar editors, comment threads. Each renders a different custom highlight via the CSS Custom Highlight API. Pre-Chrome 134 their styles were defined once on the root and then forgotten by every descendant. With highlight inheritance, each highlight cascades along its own pseudo chain — spell never picks up grammar’s style, even when ranges overlap.

probing CSS.highlights and inheritance…

Try it

Toggle each layer of highlights on a real text sample. The selected text shows a fourth highlight (::selection) — scoped to a green colour inside the boxed paragraph, blue elsewhere.

spell grammar comment selection (root) selection (.scoped)

The qiuck brown fox jumpd over the lazy dog. Less is more, except when it isnt — and that paragraph contains both a spelling problem and a grammar suggestion in roughly the same place, with a reviewer comment over the whole sentence.

This second paragraph lives inside a scoped block. Try selecting any text here. The selection turns emerald because .scoped ::selection overrides the root ::selection through the highlight inheritance chain, while the custom highlights keep their own styles.

Why this needed the spec change

/* before highlight inheritance: this only styled the root.
   Children silently used the engine defaults. */
:root ::selection      { background: blue; }
:root ::highlight(spell) { text-decoration: red wavy underline; }

/* after highlight inheritance: child overrides cascade
   through the highlight chain, not the element chain.
   Each highlight type inherits independently. */
.scoped ::selection { background: green; }  /* takes effect */

see also