49

I want an Vista/7-aero-glass-style effect on a popup on my site, and it needs to be dynamic. I'm fine with this not being a cross-browser effect as long as the site still works on all modern browsers.

My first attempt was to use something like

#dialog_base {
  background:white;
  background:rgba(255,255,255,0.8);

  filter:blur(4px);
  -o-filter:blur(4px);
  -ms-filter:blur(4px);
  -moz-filter:blur(4px);
  -webkit-filter:blur(4px);
}

However, as I should have expected, this resulted in the content of the dialog being blurred and the background staying clear. Is there any way to use CSS to blur the background of a semitransparent element instead of its contents?

2
  • 1
    In case you haven't visited this website already
    – Morpheus
    Commented Jan 28, 2013 at 16:43
  • 1
    @Morpheus I don't see how this helps me.
    – Ky -
    Commented Jan 28, 2013 at 18:50

6 Answers 6

34

OCT. 2016 UPDATE

Since the -moz-element() property doesn't seem to be widely supported by other browsers except to FF, there's an even easier technique to apply blurring without affecting the contents of the container. The use of pseudoelements is ideal in this case in combination with svg blur filter.

Check the demo using pseudo-element

(Demo was tested in FF v49, Chrome v53, Opera 40 - IE doesn't seem to support blur either with css or svg filter)


The only way (so far) of having a blur effect in the background without js plugins, is the use of -moz-element() property in combination with the svg blur filter. With -moz-element() you can define an element as a background image of another element. Then you apply the svg blur filter. OPTIONAL: You can utilize some jQuery for scrolling if your background is in fixed position.

See my demo here

I understand it is a quite complicated solution and limited to FF (element() applies only to Mozilla at the moment with -moz-element() property) but at least there's been some effort in the past to implement in webkit browsers and hopefully it will be implemented in the future.

6
  • I've just tried this in Chrome and it seems to be working for me.
    – cjm2671
    Commented Jun 7, 2013 at 9:21
  • 7
    The only truly cross-browser blur I've found is Stackblur: quasimondo.com/StackBlurForCanvas/StackBlurDemo.html
    – Imperative
    Commented Dec 13, 2013 at 8:34
  • @Imperative That's really cool, but how can it work with my setup?
    – Ky -
    Commented Jun 8, 2015 at 16:27
  • @Supuhstar I'd have to know more about your setup. That blur is using HTML5's canvas element. More recently, I just let Compass handle the cross browser CSS - compass-style.org/reference/compass/css3/filter
    – Imperative
    Commented Jun 9, 2015 at 18:51
  • 1
    @supuhstar My bad, I didn't realize you were the OP until after I typed that. I'll update my 2013 comment and suggest you have a look at blurjs.com
    – Imperative
    Commented Jun 9, 2015 at 21:04
29

In recent versions of major browsers you can use backdrop-filter property.

HTML

<div>backdrop blur</div>

CSS

div {
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
}

or if you need different background color for browsers without support:

div {
    background-color: rgba(255, 255, 255, 0.9);
}

@supports (-webkit-backdrop-filter: none) or (backdrop-filter: none) {
    div {
        -webkit-backdrop-filter: blur(10px);
        backdrop-filter: blur(10px);
        background-color: rgba(255, 255, 255, 0.5);  
    }
}

Demo: JSFiddle

Docs: Mozilla Developer: backdrop-filter

Is it for me?: CanIUse

2
  • This is the ideal answer! Can't wait til all evergreen browsers have this :D
    – Ky -
    Commented Dec 11, 2016 at 19:26
  • The JSFiddle doesn't seem to be working in Safari 10.1.2.
    – Jules
    Commented Mar 11, 2018 at 11:46
17

You can use a pseudo-element to position as the background of the content with the same image as the background, but blurred with the new CSS3 filter.

You can see it in action here: http://codepen.io/jiserra/pen/JzKpx

I made that for customizing a select, but I added the blur background effect.

5
  • Promising, but it doesn't quite work as expected: codepen.io/anon/pen/bmxad
    – Ky -
    Commented Sep 4, 2013 at 12:41
  • Of course, you have to make some modifications. If you move the div, you have to move the background-position of the div: codepen.io/jiserra/pen/JzKpx Commented Sep 4, 2013 at 15:52
  • Does this work when background content is text? This will be used for a popup dialog on a site with very few images.
    – Ky -
    Commented Sep 9, 2013 at 14:58
  • Specifically, the CSS rule is -webkit-filter: blur(4px); -moz-filter: blur(4px); filter: blur(4px); Commented Oct 20, 2013 at 20:43
  • strangely the hack you are using does not seem to work when using a normal div instead of the content: ''
    – Toskan
    Commented Jan 18, 2015 at 0:30
8

There is a simple and very common technique by using 2 background images: a crisp and a blurry one. You set the crisp image as a background for the body and the blurry one as a background image for your container. The blurry image must be set to fixed positioning and the alignment is 100% perfect. I used it before and it works.

body {
    background: url(yourCrispImage.jpg) no-repeat;
}

#container {
    background: url(yourBlurryImage.jpg) no-repeat fixed;
}

You can see a working example at the following fiddle: http://jsfiddle.net/jTUjT/5/. Try to resize the browser and see that the alignment never fails.


If only CSS element() was supported by other browsers other than Mozilla's -moz-element() you could create great effects. See this demo with Mozilla.

6
  • The problem is that this doesn't work when there's dynamic textual content behind the dialog. I know of this trick, as I've seen it used on e926.net
    – Ky -
    Commented Jan 28, 2013 at 18:48
  • There's also an experimental approach to blur everything behind the dialog but it only works in mozilla with the -moz-element() property. Basically, you define an element as a background of another element. Then you can use the svg feGaussianBlur filter to blur the background fill. You can see a live demo I've made: jsfiddle.net/2VzgL . However, the element() property is only available in mozilla and no other browser supports it yet. My hint for cross-browser compatibility would be the use of js libraries and customize them as needed, like Pixastic.
    – otinanai
    Commented Jan 29, 2013 at 15:56
  • 1
    Seems promising, but your jsFiddle doesn't behave predictably when scrolling
    – Ky -
    Commented Jan 29, 2013 at 16:03
  • 3
    The previous jsFiddle was just an example for the -moz-element() property. To behave as expected when scrolling it needs a slightly different implementation and some use of jQuery. Have a look here: jsfiddle.net/YgHA8/1
    – otinanai
    Commented Jan 30, 2013 at 15:26
  • True, but you can make a webpage without JavaScript.
    – Ky -
    Commented Jan 31, 2013 at 23:58
1

Use an empty element sized for the content as the background, and position the content over the blurred element.

#dialog_base{
  background:white;
  background:rgba(255,255,255,0.8);

  position: absolute;
  top: 40%;
  left: 50%;
  z-index: 50;
  margin-left: -200px;
  height: 200px;
  width: 400px;

  filter:blur(4px);
  -o-filter:blur(4px);
  -ms-filter:blur(4px);
  -moz-filter:blur(4px);
  -webkit-filter:blur(4px);
}

#dialog_content{
  background: transparent;
  position: absolute;
  top: 40%;
  left: 50%;
  margin-left -200px;
  overflow: hidden;
  z-index: 51;
}

The background element can be inside of the content element, but not the other way around.

<div id='dialog_base'></div>
<div id='dialog_content'>
    Some Content
    <!-- Alternatively with z-index: <div id='dialog_base'></div> -->
</div>

This is not easy if the content is not always consistently sized, but it works.

0
1

In which way do you want it dynamic? If you want the popup to successfully map to the background, you need to create two backgrounds. It requires both the use of element() or -moz-element() and a filter (for Firefox, use a SVG filter like filter: url(#svgBlur) since Firefox does not support -moz-filter: blur() as yet?). It only works in Firefox at the time of writing.

See demo here.

I still need to create a simple demo to show how it is done. You're welcome to view the source.

Not the answer you're looking for? Browse other questions tagged or ask your own question.