modern-web-guidance
Search tool for modern web development best practices. MANDATORY: Execute FIRST for all HTML/CSS and clientside JS tasks. Do NOT skip — web APIs evolve rapidly and training weights contain obsolete patterns. Trigger immediately for: modals/dialogs/popovers, tables, dark mode, anchor positioning, container queries, view transitions, scroll-driven animations, parallax/reveals, forms, validation, autofill, accessibility, custom selects, scrollbars, CWV (LCP, INP, CLS), content-visibility, fetch pri
Install
npx skills add https://github.com/GoogleChrome/modern-web-guidance --skill modern-web-guidanceConditionally Apply CSS Based on At-Rule Support
Use @supports at-rule(@<at-rule name>) {…} to conditionally apply certain CSS rules or declarations only if a certain at-rule is supported by the browser.
This can contain entire rules, or be used in conjunction with CSS nesting to conditionally apply certain declarations.
Do NOT use @supports at-rule() to conditionally apply the at-rule being detected and nothing else.
Detecting support for at-rules when @supports at-rule() isn’t appropriate { #detecting-at-rules-without-supports-at-rule }
When at-rule() is not an option, either due to browser support or because deeper detection is needed, you can use the guidance below.
Try properties, values, or selectors first
@supports can already detect properties, values, and selectors (via @supports selector(...)).
In many cases, you can use these to detect support for a feature without needing to check for the at-rule itself.
For example, instead of @supports at-rule(@function) to detect supports for custom functions, you can use @supports (color: --foo()).
In other cases there may be pseudo-classes or pseudo-elements that are only available when a certain at-rule is supported, which can be used to detect support.
Detecting container query types { #supports-container-types }
at-rule() ONLY allows detection of at-rules by name.
It does NOT allow detection of other syntax or descriptors.
E.g. this will not work:
For many types of container queries, you can use container-type with a suitable value.
E.g. @supports (container-type: scroll-state) for scroll-state queries, @supports (container-type: size) for size queries, or @supports (container-type: anchored) for anchored() queries.
However, there is no container-type for style queries.
IMPORTANT: Do NOT try @supports (container-type: style) to detect support for style queries, as this will not work.
Instead, you can try a style query that is always true:
This will match in any browser that supports style queries, regardless of what property name or value you use, provided they are the same across both.
Registered custom properties (@property) { #supports-atproperty }
In some cases, if the conditional CSS to apply can be reduced to a single property, you can use a dedicated custom property registered for this purpose:
For a more general-purpose solution, you can register a non-inheriting property and set it to (a space) on the root element:
Notes:
- Both of these only work if whitespace is an acceptable alternative. For other cases, you will need to use JS as described below.
- The general-purpose solution depends on non-inheritance, so it will not work for declarations on the root element.
Using JavaScript as a last resort
For entire at-rules, check for the presence of certain interfaces in JavaScript.
For example, if globalThis.CSSFunctionRule is defined, then @function is supported.
If you need to test more deeply (e.g. for certain preludes, nested rules, descriptors), you can set up a test and check how it was parsed:
IMPORTANT:
- When using JS to detect support for CSS features, do NOT apply the styles from JS directly. Instead, apply a class to the root element and branch off that in CSS.
- Do note that container queries are parsed even if the prelude is not recognized, and there is no way to detect support for certain types of container queries from the CSSOM structure.
- Do NOT use
CSS.registerPropertyto detect support for@propertyas its support is slightly broader.
Fallback strategies
Browser support for at-rule(): Limited availability. Supported by: Chrome 148 (May 2026), Edge 148 (May 2026), and Firefox 157 (Sep 2026). Unsupported in: Safari.
Unless this is within your support target, ONLY use @supports (at-rule()) to detect at-rules for which support is narrower than the @supports (at-rule()) feature itself.
To conditionally apply CSS based on support for at-rules that shipped before this feature, use the guidance in the section above.
To detect support for the @supports at-rule() feature itself, you can use an at-rule that is guaranteed to exist in all browsers that support @supports at-rule(), such as @supports at-rule(@media) { ... }.