CSS Highlight Inheritance has Shipped!
The CSS highlight inheritance model describes the process for inheriting the CSS properties of the various highlight pseudo elements:
::selection
controlling the appearance of selected content::spelling-error
controlling the appearance of misspelled word markers::grammar-error
controlling how grammar errors are marked::target-text
controlling the appearance of the string matching a target-text URL::highlight
defining the appearance of a named highlight, accessed via the CSS highlight API
The feature has now launched in Chrome 131 134, and this post describes how to achieve the
old selection styling behavior if selection is now not visible, or newly visible,
on your site.
The most common problem comes when a site relies on ::selection
properties only
applying to the matched elements and not child elements. For example, sites don’t
want <div>
elements themselves
to be visible, but do want the text content inside them to show the selected text.
Some sites may have used such styling to work around old bugs in browsers whereby
the highlight on the selected <div>
would be too large.
Previously, this style block would have the intended result:
<style>
div::selection {
background-color: transparent;
}
</style>
With CSS highlight inheritance the children of the <div>
will now also have
transparent selection, which is probably not what was intended.
There’s a good chance that the selection styling added to work around bugs is no longer needed. So the first thing to try is removing the style rule entirely.
Should you really want to style selection on an element but not its children,
turn to custom properties. Define a custom property for each property value that should
only apply to one matched element but not its children. In this case, that would be the
background-color
:
<style>
:root {
--selection-background-color: Highlight;
}
:root::selection {
background-color: var(--selection-background-color, Highlight);
}
div::selection {
--selection-background-color: transparent;
}
</style>
Highlight
is the system default selection background color, whatever that might
be in the browser and operating system you are using.
An alternative is to use a universal selector to set the behavior for almost all elements, and then a more specific selector for elements that need special treatment. For example, one site had this CSS:
<style>
.special-selection::selection {
background-color: magenta;
color:aqua;
}
</style>
Before Highlight Inheritance, only elements with the .special-selection
class received
aqua on magenta selection highlighting. With Highlight Inheritence, all their child elements
also received the special colors. The solution to this problem is to add a universal selector
and rely on specificity:
<style>
*::selection {
background-color: Highlight;
color: HighlightText;
}
.special-selection::selection {
background-color: magenta;
color:aqua;
}
</style>
While an element with class .special-selection
matches both selectors, the class selector is
more specific so properties there take precedence over those in the universal selector.
You must be careful to include all the properties from .special-selection
in the universal
selection to prevent any properties inheriting from .special-selection
.
There are other situations, but building on the examples we suggest some general principles:
- Make use of the CSS system colors
Highlight
andHighlightText
to revert selection back to the platform default. - Use custom properties, which still use the former inheritence model.
- Use the universal selector to set highlight properties on all elements not explicitly matched by another rule.
Chrome issue 374528707 may be used to report breakage due to enabling CSS highlight inheritance and to see fixes for the reported cases.