Testing selector support with @supports
While updating the Conditional CSS
chapter of CSS Master, I encountered a new-to-me feature of the CSS Conditional Rules Module: the selector()
function.
You may be familiar with the Conditional Rules Module, the specification that defines, @supports
and the CSS.supports()
API. With @supports
, you can add CSS rules that the browser applies only when it supports a particular property and value. For example, you might add styles that only apply when the browser supports masonry layouts for CSS Grid.
@supports ( grid-template: masonry / repeat(6, 1fr) ) {
.grid {
display: grid;
gap: 1rem;
/* Short hand for grid-template-rows / grid-template-columns */
grid-template: masonry / repeat(6, 1fr);
}
}
The level 4 draft of the Conditional Rules specification extends the @supports
rule so we can also conditionally apply rules based when the browser supports a particular selector.
Selectors Level 4, for example, added an optional, of S clause to the definition of the :nth-child()/:nth-last-child()
pseudo-classes. To date, however, few browsers support it. Using the selector()
function with @supports
lets us apply CSS in those browsers that do.
@supports selector( path:nth-child(2 of .hex) ) {
path:nth-child(2 of .hex) {
fill: magenta;
}
}
The selector()
function accepts a selector as an argument. As with other @supports
conditions, you do not need to enclose it in quotes.
Browser support for selector()
is widespread and implementations are pretty consistent across browsers, even though the specification is a work in progress. Whether you need to use the @supports selector()
, however, is a tougher call.
According to the rules of CSS parsing and error handling, browsers ignore rules that they don't understand. If a browser doesn't support a selector, the ruleset won't be applied. With that in mind, you may find it more useful to use @supports selector()
with the negation keyword to apply styles when a selector is not supported.
@supports not selector( path:nth-child(2 of .hex) ) {
path:nth-child( 3 ) {
fill: magenta;
}
}
Testing selector()
support with DOM Scripting
The @supports
at-rule has a corresponding API, that you can also use with the selector()
function.
const supportsOfS = CSS.supports( 'selector( path:nth-child(2 of .hex)' );
When using selector()
with CSS.supports()
, enclose the entire clause in quotation marks. Otherwise the script parsing engine will misinterpret selector
as a JavaScript function. You'll get a ReferenceError
.
Get CSS Master, third edition
Did you learn something from this blog post? You might like the third edition of CSS Master. It contains several nuggets of CSS joy like this one.