# Backdrop filter in CSS: frosted glass that stays fast

[Canonical HTML page](https://gradiently.design/guide/css-blur-background)

Frosted glass takes three lines of CSS and can still make a good phone stutter. Here is the code, what it costs to draw, and the fallbacks that keep words readable when the blur never arrives.

## The short version

- The CSS backdrop filter applies effects such as blur to the area behind an element, not to the element itself.
- An element needs a partly transparent background for a backdrop filter to show; on a solid background the effect is hidden.
- Blur cost grows with the blur radius and the size of the blurred area, and it is paid again every time the content behind it moves.
- Safari needed the -webkit-backdrop-filter prefix until version 18, so shipping both lines is still the safe choice.
- A good fallback is a more opaque background inside an @supports query, so text stays readable when the blur is missing.

A **backdrop filter** in CSS applies a graphic effect, usually blur, to whatever sits behind an element. Write `backdrop-filter: blur(12px)` on an element with a partly transparent background and the page beneath it softens, which is the frosted glass look used on navigation bars, sheets and cards. It is supported in every current browser. The craft lies in keeping the blurred area small, the radius modest and the fallback readable.

## The basic frosted glass recipe

Three things make glass: a translucent fill so the backdrop shows, the blur itself, and a faint edge so the panel has a shape. Most people add a small saturation boost too, because blurring averages colours and leaves them greyer than you expect.

```css
.glass {
  background: rgb(255 255 255 / 0.14);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
  backdrop-filter: blur(16px) saturate(160%);
  border: 1px solid rgb(255 255 255 / 0.22);
  border-radius: 16px;
}
```

A light glass panel for a dark or colourful page. Keep the prefixed line first so the standard property wins where both are understood.

Glass only looks like glass when there is something worth blurring behind it. On a flat grey page the panel just looks dim. Put it over a photograph or a rich gradient, as [glassmorphism](https://gradiently.design/guide/glassmorphism) explains in more depth.

Ember and violet on midnight: `radial-gradient(circle at 20% 25%, #f97316 0%, transparent 40%), radial-gradient(circle at 80% 70%, #7c3aed 0%, transparent 45%), linear-gradient(160deg, #0f172a 0%, #1e1b4b 100%)`

A backdrop with distinct patches of colour. Blur turns the patches into soft light behind the panel, which is the whole point of the effect.

## What backdrop-filter functions can do

The property accepts the same functions as `filter`, and you can chain them in one declaration. They apply in order, left to right, so `blur()` then `saturate()` behaves differently from the reverse. The full list lives on [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/backdrop-filter).

| Function | Example | Good for |
| --- | --- | --- |
| `blur()` | `blur(12px)` | Frosted glass, focus behind a dialog |
| `saturate()` | `saturate(160%)` | Putting colour back after blur greys it |
| `brightness()` | `brightness(0.7)` | Darkening a busy area behind light text |
| `contrast()` | `contrast(0.8)` | Calming a noisy photo under a panel |
| `grayscale()` | `grayscale(1)` | Muting the page behind a modal |
| `none` | `none` | Turning the effect off in a fallback or media query |

The functions you will actually use. `brightness()` below 1 is often a better legibility tool than a heavier blur.

## Backdrop filter performance

Blur is one of the more expensive things a browser draws. To blur a region it has to read every pixel behind the element, sample its neighbours out to the blur radius and composite the result, and it repeats that work whenever anything behind the panel changes. A sticky header over a scrolling page redraws its blur on every frame of the scroll.

The cost scales with two numbers you control: the area of the element and the radius. A 64 pixel header blurred at 12px is cheap on almost anything. A full screen overlay blurred at 40px over a video can drop frames on a mid range phone. The broader picture is in [CSS gradient performance](https://gradiently.design/guide/css-gradient-performance).

### Slow

- Blurring the whole viewport behind a modal
- Radii of 30px and above
- Animating the blur radius on open and close
- Glass panels nested inside glass panels
- Blur over autoplaying video

### Fast

- Blurring only the bar, card or sheet that needs it
- Radii between 8px and 20px
- Fading the panel's opacity in, with the blur fixed
- One glass layer, solid fills inside it
- Blur over still images and gradients

> **Measure on a real phone** In Chrome's developer tools, open the Rendering panel, turn on paint flashing and scroll. If the glass flashes on every frame and the Performance panel shows dropped frames, shrink the area or the radius before anything else.

## Why backdrop-filter is not working

When the blur seems to do nothing, the cause is almost always one of a short list.

1. **Check the background is see-through** A solid `background: #fff` covers the blurred backdrop completely. Use an alpha value such as `rgb(255 255 255 / 0.15)`.
2. **Add the Safari prefix** Safari only accepts the unprefixed property from version 18. Older iPhones still need `-webkit-backdrop-filter`.
3. **Look for a backdrop root above it** A parent with `filter`, `opacity` below 1, a mask, or its own backdrop filter limits what the child can see. The child then blurs only that parent, which often looks like no blur at all.
4. **Watch fixed children** Like `filter`, a backdrop filter makes the element the containing block for fixed and absolutely positioned children. A fixed menu inside a glass header will position itself against the header, not the window.
5. **Make sure something is behind it** Blur over a flat colour is invisible. Scroll the panel over an image to confirm it works.

## A fallback that keeps text readable

Translucent panels are designed around the blur. Without it, a 14 percent white fill over a busy photo leaves text sitting on the photo itself, and contrast collapses. Write the readable version first, then upgrade it where the browser can blur.

```css
/* Works everywhere: opaque enough to read on its own */
.glass {
  background: rgb(15 23 42 / 0.86);
  color: #f8fafc;
}

/* Upgrade where blur is available */
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .glass {
    background: rgb(15 23 42 / 0.45);
    -webkit-backdrop-filter: blur(14px) saturate(150%);
    backdrop-filter: blur(14px) saturate(150%);
  }
}

/* Respect people who ask for less transparency, where supported */
@media (prefers-reduced-transparency: reduce) {
  .glass {
    background: rgb(15 23 42 / 0.94);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}
```

Progressive enhancement for glass. Support for `prefers-reduced-transparency` is still limited, so treat that block as a courtesy rather than a guarantee.

Check contrast against the worst spot behind the panel, not the average. A white heading over glass that drifts across a bright sky can fall well below the ratios in [colour contrast and accessibility](https://gradiently.design/guide/color-contrast-accessibility). Darkening with `brightness(0.7)` usually fixes this more reliably than blurring harder.

## When you don't need a blur at all

Much frosted glass exists only to make words readable over a busy background. If the background is yours to design, a calmer one solves the problem at no rendering cost. A soft, low contrast gradient behind a hero needs no panel; see [website hero backgrounds](https://gradiently.design/guide/website-hero-background) and [blurred backgrounds](https://gradiently.design/guide/blurred-background), where the blur is baked into the image once instead of computed every frame.

A wide website hero with a headline running across the brightest part of a colourful gradient

Words straight over a lively background: this is where people reach for a glass panel.

The same website hero where the gradient becomes darker and quieter behind the headline

The same background calming itself behind the words, with no panel, shadow or blur.

That second approach is how Gradiently handles legibility: a Mark knows where the words are and moves its calmest, best contrasting region behind them, so you never need a box or a blur to rescue a headline.

## FAQ

### What is the difference between filter and backdrop-filter?

`filter` changes the element and its contents. `backdrop-filter` changes only what is visible behind the element, through its transparent background.

### Why is my backdrop-filter blur not showing?

Usually the element's background is fully opaque, Safari needs the `-webkit-` prefix, or a parent with `filter`, `opacity` or a mask is limiting what the element can see.

### Is backdrop-filter bad for performance?

It can be. Cost grows with the blurred area and radius and is paid again whenever the content behind moves, so keep glass panels small and radii modest.

### Do I still need -webkit-backdrop-filter?

Safari accepts the unprefixed property from version 18, but older iPhones remain in use, so shipping both lines is still sensible.

### What blur value looks best for frosted glass?

Between 8px and 20px suits most interfaces. Add `saturate()` above 100% to restore the colour blur takes away.
