Feature detect Style Queries Support in CSS

The other day on X, Adam Wathan wondered how to feature detect (Custom Property) Style Queries. While in theory you could use @supports at-rule() for this, in practice you can’t because it has no browser support (… yet).

Drawing inspiration from my previous post on how to detect support for @starting-style, I came up with a similar method to detect support for Style Queries: try actively using them and respond to that.

~

# The Code

If you are here for just the code, here it is:

html {
  --sentinel: 1;
}

@container style(--sentinel: 1) {
  body {
    --supported: ; /* Space Toggle */
  }
}

With this you get a Space Toggle for you to use in your code.

Before you tl;dr this post, you might still want to read The problem with Safari 18 section …

~

# How it works

The code works by actively trying to use a Style Query. It sets a --sentinel property on the root element and then lets the body element respond to it – using a Style Query – trying to declare the --supported custom property.

When Style Queries are supported, the result will be a --supported custom property that is set to an empty value. In browsers with no Style Queries support, the --supported property will be the guaranteed-invalid value (of initial). Yes, a Space Toggle.

With that --supported Space Toggle in place, you can then use it in your CSS:

body {
  --bg-if-support: var(--supported) green;
  --bg-if-no-support: var(--supported, red);
  background: var(--bg-if-support, var(--bg-if-no-support));
}

~

# Demo

The demo below uses the code shown earlier:

See the Pen
Feature Detect Style Queries (1/2)
by Bramus (@bramus)
on CodePen.

If you’re using Safari 18, you might notice it doesn’t work as expected …

~

# The problem with Safari 18

While Safari 18 does come with support for (Custom Property) Style Queries, you might have noticed the previous demo does not work in it.

The culprit: A bug in which the root element cannot be a container in Safari 18 – https://bugs.webkit.org/show_bug.cgi?id=271040.

To work around this bug, you need to move everything down one level in your DOM tree. Like so:

body {
  --sentinel: 1;
}

@container style(--sentinel: 1) {
  body > * {
    --supported: ; /* Space Toggle */
  }
}

This means you can’t use --supported to conditionally style the body element itself, which might be OK for your use-case.

☝️ The bug has been fixed in Safari Technology Preview 204 and should be included in Safari 18.1 when released.

~

# Safari 18-friendly demo

Here’s a demo of the code that also works in Safari. Note that it can’t be used to style the body element itself.

See the Pen
Feature Detect Style Queries (2/2)
by Bramus (@bramus)
on CodePen.

~

# Spread the word

Feel free to repost one of the posts from social media to give them more reach, or link to this post from your own blog.

~

Published by Bramus!

Bramus is a frontend web developer from Belgium, working as a Chrome Developer Relations Engineer at Google. 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 …)

Unless noted otherwise, the contents of this post are licensed under the Creative Commons Attribution 4.0 License and code samples are licensed under the MIT License

Leave a comment

Your email address will not be published. Required fields are marked *

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