CSS Feature Queries

By

Tagged: CSS

Learn how to use CSS feature queries with the @supports keyword to check if a browser supports a feature like display: grid, plus the and, or and not logic.

Feature queries let you ask the browser, directly in CSS, if it supports a feature. You write a condition using the @supports keyword, and the rules inside the block only apply when the test passes. They are a well supported part of CSS.

Why do feature queries exist?

CSS already has a fallback mechanism: when a browser meets a declaration it does not understand, it ignores that single line and moves on.

That works for one property. It does not work when a whole layout depends on a feature.

Think about CSS Grid. If the browser supports it, you want one set of rules. If it doesn’t, you want a different layout, maybe based on Flexbox. Feature queries let you group those rules and apply them all together, or not at all.

How to write a feature query

You wrap a property and value pair in parentheses after @supports:

@supports (display: grid) {
  .gallery {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
  }
}

We check if the browser supports the grid value for the display property. If it does, the rules inside the block apply.

You can use @supports for any CSS property, to check any value:

@supports (position: sticky) {
  .site-header {
    position: sticky;
    top: 0;
  }
}

Combining conditions

We can use the logical operators and, or and not to build complex feature queries.

This example checks if the browser supports both CSS Grid and Flexbox:

@supports (display: grid) and (display: flex) {
  /* apply this CSS */
}

With not you can target browsers that lack a feature, and give them a fallback layout:

@supports not (display: grid) {
  .gallery {
    display: flex;
    flex-wrap: wrap;
  }
}

A common mistake

Each condition needs its own parentheses, with both the property and the value inside.

This is invalid, and the browser ignores the entire block:

@supports display: grid {
  /* never applied */
}

Write @supports (display: grid) instead.

One more thing to keep in mind. Put your base styles outside the query, and only the enhancements inside. A really old browser that doesn’t understand @supports at all skips the whole block, so the page must still work without it.

Want me to talk about your product? You can sponsor this site.

Related posts about css: