CSS: checking support for selectors

@supports is a good way to apply an entire block of styles only if (modern) browsers support a particular property-value combo. There is no similar block-level mechanism for selector support. Selectors are automatically ignored if their values or syntax aren’t recognized by the browser, so they basically already do this at the ruleset level.

Except, sometimes you want to apply styles to other elements that don’t use the selector, but only if the browser supports the selector. One way to do this is to add a fake selector to the selector list (ie with a comma) that will not apply to any elements in the document, but has the selector piece you want to test support for. This works by the same mechanism previously mentioned, because all selectors in a list are ignored if any of them have unrecognized values. Since _ is a valid type selector in CSS, but not likely to ever become an actual element, we can base our selector off of that.

So, lets use the currently poorly supported :focus-visible pseudo-element as an example. Lets say we want to use it to show an outline focus ring on elements for keyboard focus, but not (theoretically) mouse clicks. We could do something like:

:focus{
    outline: none;
}
:focus-visible{
    outline: 2px dotted;
}

but that would give no focus ring at all to browsers that don’t recognize :focus-visible. We can instead do:

:focus, _:focus-visible{
    outline: none;
}
:focus-visible{
    outline: 2px dotted;
}

Now, browsers that don’t recognize :focus-visible don’t have the regular :focus outline removed.