Search code examples
javascripthtmlcsssvgwebkit

WebKit-like Frosted Glass in Other Browsers


WebKit's backdrop-filter has proven to be extremely helpful. I used it to create a demo for a design I've been working on that is highly reliant on the "frosted glass" aesthetic, but was dismayed to find that it has minimal cross-browser support, working only in Safari unless an experimental mode is enabled in Opera or Chrome.

I'd like my design to be functional across browsers, so I've looked into a few other solutions for creating a frosted glass blur. So far, I've encountered articles and Stack Overflow questions on how to blur images or videos, but have been unable to find any solutions that would blur parts of a div. -webkit-filter has worked across a few more browsers, but does not solve my problem, since I need to blur only specific parts of divs rather than the entire div.

I've created a demo of the background blur I'm going for. It only works in Safari at the moment, as previously explained. Is there any way that I can recreate this in other browsers in compliance with the following requirements?

  • Does not force users to enable "experimental features" in Chrome or Opera
  • Does not require programmatically taking screenshots of the area behind the modal (see demo for an example of what the modal should look like) and then blurring them with an SVG filter
  • Is responsive
  • Has optimal cross-browser support

EDIT: To demonstrate what I'm referring to, here are two images that do or do not do what I'd like to achieve:

Incorrect (from my demo, shown in the Vivaldi (Chromium) browser): Incorrect frosted glass effect In this setup, there is no blur; only a transparent overlay.

Correct (from my demo, shown in Safari): Correct frosted glass effect In this setup, the modal window blurs only the items directly behind it, rather than blurring entire divs.

I'm also curious as to whether an SVG solution would work at all, if nothing else is possible. I use an SVG editor to create my mockups, and am able to perform a background blur using that software, so I wonder if writing my entire webpage in SVG would be an impractical but suitable solution.


Solution

  • Here's how you can do a opaque blur on a selection with an SVG filter. You'd apply to HTML content using filter: url(#frost-me);. This is cross browser with two exceptions: Edge/IE where you'd have to do it all in SVG & Firefox. To get it to work in firefox you need to replace the feImage object reference with an inlined svg/xml data URI because firefox doesn't support object references in feImage. Also - animating this will require JavaScript.

     <svg width="0" height="0">
      <defs>
        <rect id="frosty-area" rx="10" ry="10" fill="red" x="460" y="100" width="400" height="300"/>
        <filter id="frost-me" x="0%" y="0%" width="100%" height="100%">
          <feImage xlink:href="#frosty-area"/>
          <feComposite operator="in" in="SourceGraphic" result="selection"/> 
          <feGaussianBlur stdDeviation="10"/>
          <feComponentTransfer>
            <feFuncA type="discrete" tableValues="1 1"/>
          </feComponentTransfer>
          <feComposite operator="in" in2="selection"/> 
          <feComposite operator="over" in2="SourceGraphic"/>
        </filter>
      </defs>
    </svg>
    

    Quick demo - just threw it into the body CSS: https://codepen.io/mullany/pen/mwrejb