v158 · css · custom highlight api
Universal base style
Everything on this page except one selector ships in every current Chrome: Highlight objects over real Ranges, the CSS.highlights registry, named ::highlight(name) rules. The one new thing — ::highlight(*) — is injected through a constructed stylesheet so you see the parser’s real verdict, and the per-name repetition you ship today runs beside it as the clearly-labelled fallback.
Three live highlights
The paragraph below has three registered highlights — no <span> wrappers, inspect the DOM — built with a TreeWalker and Range objects at load time.
The Custom Highlight API lets a spel-chekker underline suspect words, lets a grammar pass flag sentences what read badly, and lets a glossary tint a term like pseudo-element — all without wrapping text in extra elements.
what the inject button really does
const sheet = new CSSStyleSheet();
try {
// An unknown selector makes insertRule throw SyntaxError —
// this probe CAN fail, and does on every pre-158 engine.
sheet.insertRule(
"::highlight(*) { background-color: var(--bg-stone); " +
"text-decoration: underline dotted; }");
document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
} catch (e) {
// SyntaxError: ::highlight(*) is not a valid selector here
}
// The fallback you ship today — same declarations, once per name:
// ::highlight(spelling), ::highlight(grammar), ::highlight(term) { … }
Note the double check available: CSS.supports("selector(::highlight(*))") gives the static answer, and insertRule gives the enforcing one. The page reports both — they must agree.