Feature Detecting “Undetectable” CSS Features with @supports named-feature()

In CSS you can feature detect support for things like selectors, properties + values, and at-rules using @supports. But how do you feature detect a change to an underlying implementation, or two existing properties suddenly working together? Enter @supports named-feature(), a function designed to expose these specific capabilities without relying on hacky workarounds.

~

The OG use-case: “Flexbox Gap”

Back in the day (and by back in the day, I mean 2020 😅), I wrote about the gap property for Flex layouts landing in Chromium. The property already worked with Grid Layouts, and the post celebrated the property also starting to have an effect on Flex layouts.

Historically, this gap property debuted in 2015 as grid-gap (as a shorthand for grid-row-gap and grid-column-gap), and worked exclusively for CSS Grid Layout. Later on, in 2017, driven by author demand, the CSS Working Group decided that spacing out items was useful across all layout methods. So they dropped the grid- prefix and created the shorthand gap property (and its longhands row-gap and column-gap) that applies to both Grid and Flex layouts.

- grid-gap: 2em;
+ gap: 2em;

Browsers followed suit, and started treating grid-gap as an alias for the newly created gap property. But — BUT! — that didn’t mean that gap also immediately worked with Flex layouts in browsers. While aliasing grid-gap to gap was quick and easy, there was a massive gap (pun intended 🥁) between it being specced to work with Flex layout and a browser actually supporting “Flexbox gap”.

During this limbo, there was no straightforward way to detect whether the browser supported “Flexbox gap” or not. You couldn’t do @supports (gap: 1em) because the browser would truthfully say “Yes! I support that!” (for Grid). You also couldn’t do @supports (display: flex), as the browser also said yes. And combining both — through @supports (display: flex) and (gap: 1em) — also didn’t work because the browser only checks whether it can parse the passed in <suppports-condition>s, not whether they have a combined effect.

/* This only checks if CSS can parse these declarations, not if they work together */
@supports (display: flex) and (gap: 1em) {
  …
}

So right after Chromium shipped “Flexbox Gap” in 2020, I filed w3c/csswg-drafts#5062 at the CSS Working Group asking how to properly feature detect gap also playing nice with Flexbox.

Turns out this was already on their radar, and the request got duped into the more generically worded w3c/csswg-drafts#3559 from 2019, which was about “testing support of properties and values with partial implementations”.

~

Enter named-feature()

The discussion in w3c/csswg-drafts#3559 eventually turned silent but at the end of 2023 it became very relevant again as browsers were about to support align-content having an effect on display: block containers.

Two months later, the Working Group accepted a proposal by David Baron to solve this. I really like David’s original pitch to solving this problem:

I think it might be reasonable to add specific, one-off solutions when we think they’re important enough. They’d need to be for significant enough features that we’d be willing to add an extra keyword to CSS for them, and that an implementor wouldn’t miss that it needed to be implemented, and that we’d be willing to write specific web-platform-tests to verify and monitor the results closely to make sure the rollout doesn’t go wrong. And we could probably choose reasonably verbose keywords.

The result is named-feature(), which is a function that allows you to feature-detect very specific behaviors or behavior changes that cannot be caught using the traditional @supports-checks. The function require a keyword as its argument, and the list of allowed keywords is predefined in the spec.

@supports named-feature(some-specific-behavior) {
  /* CSS for browsers that support 'some-specific-behavior' here … */
}

Keywords are only added for the handful of tricky edge cases where feature detection is highly requested but impossible to do using other mechanisms in CSS.

~

Real-World Use Cases

Currently the CSS Working Group has specified two keywords for named-feature(). I’m quite happy about these, as I proposed both of them at the Working Group 🙂

~

1. Transform-Aware Anchor Positioning

CSS Anchor Positioning initially shipped without taking transforms into account. Because author demand was huge, things changed and the spec got updated to support this use-case. The change shipped in Chrome 144, is included in the upcoming Safari 27, and is currently being prototyped in Firefox.

While you could already easily feature detect Anchor Positioning itself, you couldn’t detect if the browser respects transforms on the anchor. To solve this, you can now use the keyword that was resolved on in w3c/csswg-drafts#13678: anchor-position-follows-transforms.

@supports named-feature(anchor-position-follows-transforms) {
  /* ✅ The browser supports transform-aware anchor positioning! */
}

While not originally slated for their 27.0 release — the release that includes Transform-Aware Anchor Positioning — I reached out to the Safari team to add support for named-feature(anchor-position-follows-transforms), and the PR got merged earlier this month. Firefox is currently prototyping Transform-Aware Anchor Positioning, and they announced that they will ship named-feature() simulatenously.

~

2. Single-Axis Scroll Containers

Another feature that needs more advanced feature detection is the recent change that allows containers to be a scroller for only a single axis. This fixes a longstanding issue where position: sticky on one axis gets trapped by an unrelated scroller on the other axis, as detailed in my post on CSS sticky per axis.

While you can feature detect Single-Axis Scroll Containers by throwing lots of JavaScript at the problem, there was no way to do this in CSS. But thanks to my proposal in w3c/csswg-drafts#13677, we now have the single-axis-scroll-container keyword for use with @supports named-feature(single-axis-scroll-container):

@supports named-feature(single-axis-scroll-container) {
  /* ✅ Single-axis scroll containers are supported, so sticky per axis just works! */
}

~

# Browser Support

💡 Although this post was originally published in August 2026, the list below is constantly being updated. Last update: August 27, 2026.

Support for named-feature() looks as follows:

Chromium (Blink)

✅ Supported in Chrome 150

Firefox (Gecko)

☑️ Supported in Firefox 156 (soon in beta)

Safari (WebKit)

☑️ Supported in Safari Technology Preview

What is more interesting though, is support for the various keywords.

Support for anchor-position-follows-transforms:

Chromium (Blink)

✅ Supported in Chrome 150

Firefox (Gecko)

☑️ Supported in Firefox 156 (soon in beta)

Safari (WebKit)

☑️ Supported in Safari Technology Preview

Support for single-axis-scroll-container:

Chromium (Blink)

✅ Supported in Chrome 153

Firefox (Gecko)

❌ No Support. There is no bug tracking this yet.

Safari (WebKit)

❌ No Support. There is no bug tracking this yet.

~

What about other features?

If you are wondering about the older features I mentioned here, and whey they don’t have a keyword, here’s why:

CSS gap with display: flex
All browser support this by now. Too much time has passed since it shipped and this feature detection through named-feature() becoming available.
align-content having an effect on display: block
Chrome did it’s homework and did (internal) testing against the top X websites. The only notable breakage that came out of that was Netflix being broken (they had align-content on an element that switched from block to flex through a media query) but we got them to fix their CSS.

And then there’s also these features that are currently hard to detect:

Style Queries

I have filed w3c/csswg-drafts#13975 for it a while ago. The tricky thing with it though, is that a lot of time has passed since Chrome first shipped it in March 2023 and Safari in September 2024 … so shipping a check now would yield a lot of false negatives. Additionally, there is a documented workaround to feature detect style queries.

For completeness: Other at-rules — such as @property — can be feature detected using at-rule().

~

Spread the word

Feel free to reshare one of the following posts on social media to help spread the word:

~

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

I can also be found on 𝕏 Twitter and 🐘 Mastodon but only post there sporadically.

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.