
The Future of CSS: Detect at-rule support with @supports at-rule(@keyword)
The Future of CSS: Detect at-rule support with @supports at-rule(@keyword) êŽë š

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 (w3c/csswg-drafts) 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](/bram.us/the-future-of-css-scroll-linked-animations-part-1.md, 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 (w3c/csswg-drafts) 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 (w3c/csswg-drafts) 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: