CSS Feature Queries
By Flavio Copes
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.
Related posts about css: