CSS Grid
CSS @supports
A CSS @supports rule — known as a feature query — lets your stylesheet ask the browser whether it understands a particular property or value, and apply CSS only when the answer is yes. It is the CSS equivalent of feature detection, and the key tool for progressive enhancement.
What is @supports?
@supports wraps a block of CSS in a condition that tests support for a property:value pair. If the browser supports it, the rules inside apply; if not, they are ignored and your fallback stays in place. This lets you use cutting-edge CSS while keeping older browsers functional.
@supports (display: grid) {
.layout {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
}The Fallback-First Pattern
The recommended approach is to write a simple fallback first, then enhance it inside @supports. Older browsers use the fallback; modern ones get the upgrade. This is the essence of progressive enhancement.
/* Fallback for every browser */
.gallery { display: flex; flex-wrap: wrap; }
/* Enhancement only where grid is supported */
@supports (display: grid) {
.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
}Combining Conditions
Feature queries support logical operators, so you can test several conditions together.
| Operator | Meaning | Example |
|---|---|---|
| and | All conditions must be supported | @supports (gap: 1rem) and (display: grid) |
| or | At least one must be supported | @supports (position: sticky) or (position: -webkit-sticky) |
| not | The condition must NOT be supported | @supports not (display: grid) |
@supports (display: grid) and (gap: 1rem) {
.grid { display: grid; gap: 1rem; }
}
@supports not (aspect-ratio: 1) {
/* apply an old padding-hack fallback here */
}A Runnable Feature Query
The example below tests support for a value and shows a message. In any modern browser you will see the green success box, proving the feature query matched.
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: sans-serif; padding: 20px; }
.badge {
padding: 20px; border-radius: 8px; font-weight: 800;
color: #fff; background: #ef4444; /* fallback: red = not supported */
}
/* If the browser supports grid, turn the badge green */
@supports (display: grid) {
.badge {
background: #22c55e;
}
.badge::after { content: " — grid supported!"; }
}
</style>
</head>
<body>
<div class="badge">Feature test</div>
</body>
</html>You can also test in JavaScript with CSS.supports('display', 'grid'), which returns true or false — handy for conditional scripting.
@supports tests whether the browser understands the syntax, not whether the feature is bug-free. A property can be recognised yet still behave slightly differently across browsers.
When to Use Feature Queries
- Adopting newer layout features (grid, subgrid, aspect-ratio) with a safe fallback.
- Providing vendor-prefixed alternatives with an or condition.
- Avoiding broken layouts in browsers that lack a property.
- Cleanly separating baseline styles from progressive enhancements.
Key Points
- @supports (property: value) applies CSS only when the browser supports it.
- Write the fallback first, then enhance inside @supports.
- Combine tests with and, or and not.
- CSS.supports() offers the same check in JavaScript.
- It detects syntax support, not the absence of rendering bugs.
