v148 · CSS · @supports at-rule()
Feature Detector
Live at-rule detection for this browser. The CSS column uses @supports at-rule(…) in a stylesheet. The JS column uses CSS.supports('at-rule(@…)'). Compare the two.
runtime probe
Choose an at-rule and run the probe. Empty or malformed values are reported as invalid instead of silently failing.
At-rule
CSS @supports
JS CSS.supports()
How CSS detection works
/* Check if browser knows @layer */
@supports at-rule(@layer) {
.layered-component { ... }
}
/* Check for @starting-style (enter animations) */
@supports at-rule(@starting-style) {
dialog {
opacity: 0;
@starting-style { opacity: 0; }
transition: opacity 0.3s;
}
}
/* Check for @property (typed custom properties) */
@supports at-rule(@property) {
@property --angle {
syntax: "<angle>";
inherits: false;
initial-value: 0deg;
}
.spinner { animation: spin 1s infinite; }
}
Before @supports at-rule() — the old workaround
Before — JavaScript only
// CSS.supports() only checks property:value pairs
// It cannot check at-rule support
const hasLayer = CSS.supports('@layer');
// → always false (syntax not supported)
// Had to use browser detection or heuristics:
const isChrome105Plus = /Chrome\/(\d+)/.exec(
navigator.userAgent
)?.[1] >= 105;
if (isChrome105Plus) {
document.body.classList.add('has-layer');
}
// Brittle. User-agent sniffing = bad.
Chrome 148 — CSS + JS
/* Pure CSS: */
@supports at-rule(@layer) {
/* only if @layer is understood */
.nav { layer: nav; }
}
/* JavaScript: */
CSS.supports('at-rule(@layer)')
// → true in Chrome 99+, false older
CSS.supports('at-rule(@starting-style)')
// → true in Chrome 117+
CSS.supports('at-rule(@scope)')
// → true in Chrome 118+
references
implementation reference
Need the exact API surface, compatibility boundaries, errors, lifecycle, and source links? Read the matching gendn reference ↗