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 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

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:


To help spread the contents of this post, feel free to retweet the announcement tweet:


🔥 Like what you see? Want to stay in the loop? Here's how:

Published by Bramus!

Bramus is a frontend web developer from Belgium. From the moment he discovered view-source at the age of 14 (way back in 1997), he fell in love with the web and has been tinkering with it ever since (more …)

Leave a comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.