
Progressive Enhancement in CSS Using supports Feature Queries
Supporting older browsers does not mean every visitor must receive a lowest-common-denominator layout, nor does it require loading external JavaScript feature-detection scripts. The native @supports CSS feature query lets you ask the browser directly whether it understands a specific property: value pair before applying progressive enhancements.
Example
/* Base fallback for all browsers */
.gallery {
display: flex;
flex-wrap: wrap;
}
/* Progressive enhancement for browsers with CSS Grid */
@supports (display: grid) {
.gallery {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}
}
Input : Layout or visual effect using modern CSS properties (display: grid, backdrop-filter)
Output : Self-contained stylesheet that degrades gracefully in older browsers.
Implementation
/* 1. Solid opaque fallback header for older browsers */
.sticky-header {
position: sticky;
top: 0;
background-color: rgba(255, 255, 255, 0.96);
border-bottom: 1px solid #dedede;
}
/* 2. Frosted glass enhancement when backdrop-filter is supported */
@supports ((-webkit-backdrop-filter: blur(10px)) or (backdrop-filter: blur(10px))) {
.sticky-header {
background-color: rgba(255, 255, 255, 0.78);
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
}
}
/* 3. Grid layout enhancement with Flexbox fallback */
.feature-list {
display: flex;
flex-wrap: wrap;
margin: -10px;
}
.feature-list__item {
flex: 1 1 280px;
margin: 10px;
}
@supports (display: grid) {
.feature-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
grid-gap: 20px;
margin: 0;
}
.feature-list__item {
margin: 0;
}
}
Main Point: Structure your CSS so the base rule works everywhere, and use @supports (...) to opt into newer layout or visual properties—and remember to reset fallback margins (margin: 0) inside the @supports block.
Credits
Photo by Lauren Mancke