Core layout and readable content.
EnhancedOptional visuals when feature support exists.
Start with universal CSS, then conditionally add advanced properties.
Ship a reliable baseline first, then unlock modern CSS where support exists. This approach keeps interfaces resilient and future-friendly.
Progressive enhancement means everyone gets a functional layout. Browsers with newer features get better visuals or richer interaction.
Core layout and readable content.
EnhancedOptional visuals when feature support exists.
Start with universal CSS, then conditionally add advanced properties.
.panel {
border-radius: 12px;
background: #fff;
}
@supports (backdrop-filter: blur(10px)) {
.panel {
background: rgba(255, 255, 255, 0.2);
backdrop-filter: blur(10px);
}
}You can detect one feature, combine multiple checks with and or or, and invert checks with not.
@supports (display: grid)Enable CSS Grid only where supported.
@supports (display: grid) and (gap: 1rem)Require both features before applying enhancement.
@supports not (container-type: inline-size)Use this for explicit fallback rules.
@supports (display: grid) {
.list { display: grid; gap: 1rem; }
}
@supports not (display: grid) {
.list > * { margin-bottom: 1rem; }
}Keep a readable translucent panel as baseline and upgrade to blur where available.
Users get a good baseline even if blur support is missing.
.glass {
background: rgba(255, 255, 255, 0.6);
}
@supports ((-webkit-backdrop-filter: blur(10px)) or (backdrop-filter: blur(10px))) {
.glass {
background: rgba(255, 255, 255, 0.22);
-webkit-backdrop-filter: blur(12px);
backdrop-filter: blur(12px);
}
}Ship a flexible baseline with Flexbox and enhance to Grid where it improves symmetry.
The same markup supports both fallback and enhanced layouts.
.cards { display: flex; flex-wrap: wrap; gap: 0.75rem; }
@supports (display: grid) {
.cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
}Feature queries help you adopt logical properties, scroll-snap, and other modern APIs without breaking older browsers.
Use physical spacing as baseline and logical properties as enhancement.
Without support, the list still scrolls normally.
.chip { margin-right: 0.5rem; } /* baseline */
@supports (margin-inline: 0.5rem) {
.chip { margin-inline: 0.5rem; }
}
.timeline { overflow-x: auto; } /* baseline */
@supports (scroll-snap-type: x mandatory) {
.timeline { scroll-snap-type: x mandatory; }
}