In CSS you can do feature detection using @supports
. With it you can detect support for property-value pairs and selectors. What currently isn’t possible though, is to detect support for certain at-rules (such as @layer
, @scroll-timeline
, etc.)
Hot off the press is a new CSS Working Group decision that defines the at-rule
function — to be combined with @supports
— which will allow just that.
~
The problem
The @scroll-timeline
at-rule mentioned in this post has been discontinued in favor of scroll-driven animations with scroll()
and view()
. The problem laid out here still applies to other at-rules though. Think of feature detecting @property
, @starting-style
, @container
, etc.
While working on my articles and demos that use @scroll-timeline
, I ran into an issue: how do I feature detect support for this at-rule?
Thankfully I could use a workaround by checking for support of a “telltale” property: animation-timeline
: Browsers that have implemented @scroll-timeline
, also have implemented the animation-timeline
property. By checking for animation-timeline
‘s existence, we can feature detect support for @scroll-timeline
.
@supports (animation-timeline: works) {
/* @scroll-timeline compatible code here */
}
But detecting a telltale property isn’t always 100% accurate or possible. Take the wonderful @layer
for example: that one doesn’t come with a telltale property. How do we detect support for it?
~
The solution
To solve this, the CSS Working Group just decided to introduce a new function that be used in conjunction with @supports
: at-rule()
.
With it, we can feature detect at-rule support as follows:
@supports at-rule(@foo) {
/* @foo is supported */
}
It’s also possible to detect support for certain descriptors. For @scroll-timeline
this will come in handy, as the descriptors changed over time.
@supports at-rule(@foo; desc: val) {
/* @foo is supported. The descriptor `desc` with value `val` parses as part of that at-rule. */
}
Winging back to detect support for @layer
, the CSS would look like this:
@supports at-rule(@layer) {
/* @layer is supported */
}
~
The solution, bis
Apart from the syntax above, there’s a follow-up issue that will allow you to pass in a full at-rule into at-rule()
:
@supports at-rule(@foo bar {baz: qux}) {
/* The entire at-rule with all its descriptors is supported. Unknown descriptors are ignored. */
}
Note that in this form you’ll have to pass in a valid — thus, complete — at-rule.
~
Browser Support
This is hot off the press. Currently, no browser supports this. I’ve filed issues at all browser engines to add support for this:
- WebKit/Safari: Issue #235400
- Gecko/Firefox: Issue #1751188
- Blink/Chromium: Issue #1289224
UPDATE 2024.10.04: The Chromium bug got assigned … expect this to be worked on in Q4 🙂
~
To help spread the contents of this post, feel free to retweet the announcement tweet:
The Future of CSS: Detect at-rule support with
`@ supports at-rule(@keyword)`🔗 https://t.co/605iKCzZ62#CSS #FeatureDetection pic.twitter.com/2lwqQIR2wF
— Bram.us (@bramusblog) January 20, 2022
~
🔥 Like what you see? Want to stay in the loop? Here's how:
Leave a comment