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-filter as well.
  • A value other than none makes position: fixed elements 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-30
  • Edge

    v79+
    2020-01-15
    Prefixed
    v17 - v79
    -webkit-backdrop-filter
  • Safari

    v18+
    2024-09-16
    Prefixed
    from v9
    -webkit-backdrop-filter
  • Safari (iOS)

    v18+
    2024-09-16
    Prefixed
    from v9
    -webkit-backdrop-filter
  • Firefox

    v103+
    2022-07-26

Search by feature name or code

e.g. aspect-ratio, :has(), padding-top

Try a different word or a property name.

Could not load search.