conditional
@supports
Applies rules only when the browser supports the tested CSS feature, enabling progressive enhancement without JavaScript. Conditions can be combined with and, or, and not.
@supports (<property>: <value>) { <rules> } Common conditions / descriptors
| Descriptor | Purpose |
|---|---|
| (property: value) | True when the browser parses that declaration |
| not (...) | Negate the condition |
| and | Combine two conditions that must both hold |
| or | Combine two conditions where either may hold |
| selector(...) | Test whether a selector is understood (e.g. :has()) |
| font-tech(...) / font-format(...) | Test font capability support |
Examples
@supports (display: grid) {
.layout { display: grid; grid-template-columns: repeat(12, 1fr); }
} Only apply grid layout where grid is supported
@supports selector(:has(*)) {
form:has(:invalid) button { opacity: .5; }
} Feature-detect the :has() selector before using it
@supports not (backdrop-filter: blur(8px)) {
.glass { background: rgba(255,255,255,.85); }
} Fallback background when backdrop-filter isn't supported
@supports (color: color(display-p3 1 0 0)) {
.accent { color: color(display-p3 1 0 0); }
} Opt into wide-gamut color only when the color space is understood
Gotcha
@supports only tests parsing, not rendering correctness — a browser can accept a declaration while implementing it poorly. Place enhancement blocks after your baseline styles so they cleanly override.
Related at-rules
@media
Applies contained CSS rules only when the specified media query matches the user's device, viewport, or environment. It is the foundation of responsive design and print-specific styling.
@container
Applies rules based on the size or style of a nearest containment context rather than the viewport, enabling truly component-scoped responsiveness. Requires an ancestor that opts in via container-type.
@layer
Declares one or more cascade layers so authors can control the order in which rule groups cascade, independent of specificity. Layers declared later win over layers declared earlier, and unlayered styles win over all named layers.