backdrop-filter
Applies filters such as blur to whatever shows through behind an element. The frosted-glass look can be written without duplicating the background image.
Modern approach
Combined with a semi-transparent background color, whatever is behind the element shows through blurred. There’s no need to duplicate the background image.
.header {
position: sticky;
top: 0;
background-color: rgb(255 255 255 / 0.6);
backdrop-filter: blur(8px);
}Legacy approach
The page’s background image was laid again, fixed, in ::before and blurred with filter: blur(). This only works when what’s behind is a fixed background image, and things like body text are hidden instead of blurred. In Safari on iOS, fixed has no effect, so the blurred background is out of place.
body {
background: url("bg.jpg") center / cover fixed;
}
.header {
position: sticky;
top: 0;
z-index: 0;
overflow: hidden;
}
.header::before {
content: "";
position: absolute;
top: -16px;
right: -16px;
bottom: -16px;
left: -16px;
z-index: -1;
background:
linear-gradient(rgb(255 255 255 / 0.6), rgb(255 255 255 / 0.6)),
url("bg.jpg") center / cover fixed;
filter: blur(8px);
}Things to watch when replacing
- The unprefixed property has worked in all browsers only since September 2024, when Safari 18 added it. To also support older Safari, write
-webkit-backdrop-filteras well. - A value other than
nonemakesposition: fixedelements inside it position against that element instead of the viewport. A drawer menu placed inside the header gets trapped inside the header. - Without a semi-transparent background color, nothing behind shows through, so there’s no visible effect.
- If a parent has
opacity,filter, or similar, only what lies between that parent and the element gets blurred.
Fallback
Browsers without support show only the semi-transparent background color, without the blur. Before Firefox 123, it sometimes didn’t work depending on the GPU, with the same result. If text becomes hard to read, make the background color more opaque with @supports not.
@supports not (
(backdrop-filter: blur(8px)) or (-webkit-backdrop-filter: blur(8px))
) {
.header {
background-color: rgb(255 255 255 / 0.9);
}
}Browser Support
Chrome
v76+2019-07-30Edge
v79+2020-01-15Prefixed
v17 - v79-webkit-backdrop-filterSafari
v18+2024-09-16Prefixed
from v9-webkit-backdrop-filterSafari (iOS)
v18+2024-09-16Prefixed
from v9-webkit-backdrop-filterFirefox
v103+2022-07-26