demo · v134
Custom Highlight API
The CSS Custom Highlight API + the new inheritance rules. Toggle independent highlight registries (spell, grammar, todo, quote-callout), watch them layer on the same text, and see how ::highlight() now inherits properties through the highlight chain instead of the element chain.
painting priority
Enable spell + grammar to compare the overlapping priority word.
Editor view
The browser doesn't pre-highlight any of teh mistakes here — that's the editor's job. Each toggle above registers a different Highlight instance over the same DOM range. The word priority is deliberately covered by both spell and grammar so the sliders can change which paint wins.
A subject verb-agreement issues happens in this sentence. Grammar layer above.
The TODO: link to RFC 8941 here kind of marker is its own highlight. Different colour, no underline.
CSS.highlights.set("spell", new Highlight(range1));
CSS.highlights.set("grammar", new Highlight(range2));
CSS.highlights.set("todo", new Highlight(range3));
CSS.highlights.set("quote", new Highlight(range4));
// This demo uses selectNodeContents() for whole-node ranges.
// Editors usually use range.setStart(textNode, startOffset)
// and range.setEnd(textNode, endOffset) for character-precise spans.
.doc::highlight(spell) {
background: color-mix(in srgb, var(--accent-rose) 18%, transparent);
text-decoration: underline wavy var(--accent-rose);
}
.doc::highlight(grammar) { ... }
.doc::highlight(todo) { ... }
.doc::highlight(quote) {
background: color-mix(in srgb, var(--accent-emerald) 18%, transparent);
color: var(--accent-emerald);
}
.doc .quote::highlight(quote) {
background: color-mix(in srgb, var(--accent-emerald) 30%, transparent);
}
/* color inherits from .doc::highlight(quote) — the v134 win */
why inheritance matters here
An editor surface stacks highlight registries: spell, grammar, comments, search-match, todo, suggestion, conflict. Before v134, each registry that styled only one property (say, background) would silently lose any text-colour rule defined higher up the document. You'd have to repeat every property at every nesting level.
With highlight inheritance, you set the body-level ::highlight(spell) once and let nested elements override only the bits they want. Less CSS, no surprises, much closer to how authors expect cascading to work.