← Back to CSS Course | Chapter 9: Modern CSS Features | Lesson 12 of 25

CSS @supports

Imagine a chef who checks the pantry before committing to a recipe: 'if we have saffron, make the fancy version, otherwise make the regular one.' The kitchen doesn't break just because an ingredient is missing. @supports is that pantry check for CSS -- it lets a stylesheet test whether the browser understands a feature before relying on it.

Basic @supports Syntax

@supports wraps a block of CSS rules in a condition that tests whether the browser can parse and apply a given property-value pair, only applying the enclosed rules if the test passes. The condition itself looks like a real declaration inside parentheses.

Example: Basic @supports Syntax

css
@supports (display: grid) {
  .container {
    display: grid;
  }
}

Combining Conditions with and/or/not

Multiple feature tests can be combined with and (all must pass), or (any must pass), and not (negates a single test), letting a feature query express fairly precise support requirements in one rule.

Example: Combining Conditions with and/or/not

css
@supports (display: grid) and (gap: 1rem) {
  .container {
    display: grid;
    gap: 1rem;
  }
}

The not Operator

Prefixing a condition with not applies the enclosed rules only when the feature is NOT supported, which is the natural way to write a true fallback path for genuinely old browsers.

Example: The not Operator

css
@supports not (display: grid) {
  .container {
    display: block;
  }
}

Progressive Enhancement Use Case

The standard pattern is to write baseline CSS that works everywhere first, then layer @supports blocks on top to opt modern browsers into enhanced layouts or effects -- rather than writing modern-only CSS and trying to patch old browsers afterward.

Example: Progressive Enhancement Use Case

css
.container {
  display: block;
}
@supports (display: flex) {
  .container {
    display: flex;
  }
}

Testing Selector Support

@supports selector(...) tests whether the browser understands a given CSS selector syntax (not just a property), useful for newer selectors like :has() that have uneven adoption.

Example: Testing Selector Support

css
@supports selector(:has(a)) {
  .card:has(a) {
    cursor: pointer;
  }
}

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.