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 CodeIf 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 worksThe 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));} ~

DemoThe 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 18While 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 demoHere’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 wordFeel free to repost one of the posts from social media to give them more reach, or link to this post from your own blog.

📝 Feature detect Style Queries Support in CSS.

Awaiting browser support for at-rule(), here’s how you do it.https://t.co/uXikYbBM2S pic.twitter.com/iuyVwlAgyX

— Bram.us (by @bramus) (@bramusblog) October 6, 2024

~

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

  • Follow @bramus on Twitter
  • Follow @bramus on Mastodon
  • Follow @bramusblog on Twitter
  • Follow bram.us using RSS