A Blur That Behaves Like a Box Shadow

CSS has a box-shadow property for producing soft edges and depth around an element. But there’s no equivalent for blurring the backdrop in a way that gradually grows weaker with distance. For a popup or dialog sitting over a busy background, a traditional shadow often doesn’t provide enough separation. A blur effect that fades out in all directions would do a better job without dissonant visual noise.

That effect isn’t available as a single built-in function, but it can be approximated by combining pseudo-elements, CSS masks, and backdrop-filter. Here’s the approach.

Structure the Element and Its Overlay

The base for this technique is any element — a dialog, tooltip, or simple <div>. The visual trick is handled entirely by that element’s ::before pseudo-element, so the HTML stays unchanged and the effect can be reused across different components.

<!-- This is literally it for this demo -->
<div></div>

The pseudo-element is positioned absolutely and inflated with a negative inset, so it spills out beyond the parent’s box. That extra space defines the visible region where the blur will appear. The effect direction is therefore scalable: the inset value acts like the spread on a box shadow.

::before {  
  content: '';

  /* Make sure the parent element is at least relatively positioned to contain the pseudo-element. */
  position: absolute;
  
  /* The blur size should be anything below `0` so it will extend to the outside. */
  inset: -100px;

  /* This layer is positioned between the parent element and page background. */
  /* Make sure this value is one below the `z-index` of the parent element. */
  z-index: -1;
}

Build a Fading Mask With Two Gradients

Gradients are treated by the browser as images, which makes them usable as mask layers. By applying a combination of masked gradients, we can selectively hide parts of the overlay. The key is transparency: an opaque mask region will show the effect while a transparent one will hide it entirely.

To create a fade that originates from the element’s edge and diminishes outward, two linear gradients are required: one vertical and one horizontal. Both are declared on the mask property. Safari needs the -webkit-mask prefix, so you should declare the prefixed version first.

  • The vertical gradient (to top) runs from transparent at the bottom to black in the middle, then to transparent at the top.
  • The horizontal gradient (to left) does the same in the lateral direction.
mask:
  linear-gradient(to top, transparent 0%, black 25% 75%, transparent 100%),
  linear-gradient(to left, transparent 0%, black 25% 75%, transparent 100%);

See the Pen [Basic Gradient Mask [forked]](https://codepen.io/smashingmag/pen/qBvXmpP) by Yair Even Or.

See the Pen Basic Gradient Mask [forked] by Yair Even Or.
-webkit-mask:
  linear-gradient(to top, transparent 0%, black 25% 75%, transparent 100%),
  linear-gradient(to left, transparent 0%, black 25% 75%, transparent 100%);
mask:
  linear-gradient(to top, transparent 0%, black 25% 75%, transparent 100%),
  linear-gradient(to left, transparent 0%, black 25% 75%, transparent 100%);

Composite the Mask Into a Rectangle

Declaring only the gradients yields a cross-shaped fade. The principle of mask-composite allows us to blend these two layers. With the value source-in, the browser retains only the areas where both gradient masks overlap. The result is a narrowly-defined rectangle that acts as the fade anchor around which the effect can be applied.

That composite mask can then be applied to any DOM element with gentle or generous border-radius.

Blur the Backdrop Behind the Mask

Once the shape is established, the backdrop-filter property does the heavy lifting. When applied to the ::before element (that is now shaped by the mask), it blurs everything rendered underneath. The intensity is set by the argument in the blur() function. In this case, a value of 10px provides a robust but non-aggressive effect.

::before {
  /* etc. */

  backdrop-filter: blur(10px);
}

As with masks, Safari needs its vendor-prefixed variant. Declare the -webkit-backdrop-filter before the standard property to provide proper fallback behavior.

::before {
  /* etc. */

  -webkit-backdrop-filter: blur(10px); /* Required for Safari */
  backdrop-filter: blur(10px);
}

Add an Optional Ambient Shadow

A subtle box-shadow with low opacity can blend with the blur and improve the perceived depth. It’s applied to the element itself, not the overlay pseudo-element, to avoid stepping outside the fade area.

div {
  box-shadow: 0 0 40px #00000099;
}

Combine All the Pieces

Here’s the complete setup once the pieces are placed together.

/* This can be set on the ::before pseudo of the element it is applied to. */
::before {    
  content: '';

  /* This layer is positioned between some element and its background. */
  position: absolute;
  
  /* This should not affect the contents of the container. */
  z-index: -1;
  
  /* The blur size should be anything below `0` so it will extend to the outside. */
  inset: -100px;
  
  /* The blur effect */
  -webkit-backdrop-filter: blur(10px); /* Required for safari */
  backdrop-filter: blur(10px);
  
  /* A mask fades the blur effect, so it gets weaker. */
  /* towards the edges, further from the container box. */
  /* (The fill color is irrelevant, so "red" is used as it's the shortest color name.) */
  mask: 
    linear-gradient(
      to top, 
      transparent 0%,
      red 100px calc(100% - 100px),
      transparent 100%), 
    linear-gradient(
      to left,
      transparent 0%,
      red 100px calc(100% - 100px),
      transparent 100%);
  
  /* This merges the masks above so only the overlapping pixels are rendered. */
  /* This creates the illusion of a fade-out mask. */
  mask-composite: intersect;
  -webkit-mask-composite: source-in; /* Required for Safari */
}

See the Pen [Faded Outer Box Backdrop Blur [forked]](https://codepen.io/smashingmag/pen/ZEPJKRO) by Yair Even Or.

See the Pen Faded Outer Box Backdrop Blur [forked] by Yair Even Or.

When you prefer clean code without variables, a simplified version is available that removes the customization layer and highlights the core mechanics directly.

Smashing Editorial