See the Pen Cross-Browser Frosted Glass effect with HTML, CSS and jQuery by Erik de Kuijper (@edkpr) on CodePen.
I was looking for a good way to use this effect for a client project. While trying different methods to go about this I found none to be quite useful to use in a production environment. I didn’t want to use the popular “blurry background on sharp background” technique you probably found when searching for a frosted glass effect, because of the obvious positioning headaches you’re going to have when working with background images. I tried a jQuery plugin that didn’t live up to my expectations. So I decided to make my own solution;
What I needed;
I thought of a way that I haven’t seen being used when doing my initial research. I decided to duplicate the image, use SVG to a blur effect, then use CSS to crop the SVG to the dimensions of the content overlay, creating a frosted glass effect that works reliably across all major browsers. The positioning of the CSS crop is going to be calculated using jQuery.
Easy enough, let’s get to it!
I decided to use SVG to create a duplicate image, and apply blur with SVG. Using SVG instead of CSS ensured cross-browser compatibility, making this work in Internet Explorer as well.
Note:
Make sure to place your own corresponding image dimensions in the viewBox tag. Also, feel free to adjust the amount of blur you want by adjusting the stdDeviation number.
<section class="banner">
<svg class="blur" viewBox="0 0 1920 700" preserveAspectRatio="xMinYMid">
<defs>
<filter id="blur">
<feGaussianBlur stdDeviation="20" />
</filter>
</defs>
<image xlink:href="https://www.wcg.de/fileadmin/masterTemplate/Resources/Public/Images/site-wcg/banner/banner-waves-01.jpg" width="1920" height="700" filter="url(#blur)"></image>
</svg>
<img src="https://www.wcg.de/fileadmin/masterTemplate/Resources/Public/Images/site-wcg/banner/banner-waves-01.jpg" width="1920" height="700" alt="Waves" />
<div class="wrap">
<div class="pad">
<a href="https://www.wcg.de/blog/detail/cross-browser-frosted-glass-effect-with-html-css-and-jquery/" target="_blank" >
Cross-Browser Frosted Glass Effect
</a>
</div>
</div>
</section>
This is pretty straightforward, the image is stretched to 100% of the viewport, with the SVG being positioned on top of that.
Note:
The positioning of the text on top of the image, is completely flexible by controlling positioning of the ".pad" div with CSS flex-properties. The blur overlay we're creating using jQuery adjusts itself to its position, so feel tree to play around with the best positioning for your project!
.banner {
position: relative;
float: left;
width: 100%;
}
.banner img {
display: block;
width: 100%;
height: auto;
}
.banner .blur {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.banner .blur image {
width: 100%;
height: 100%;
}
.banner .wrap {
position: absolute;
left: 0;
right: 0;
top: 0;
width: 100%;
height: 100%;
max-width: 1500px;
position: absolute;
padding: 3em 0;
box-sizing: border-box;
display: flex;
align-items: flex-end;
z-index: 1;
margin: auto;
justify-content: flex-start;
}
.banner .pad {
float: left;
width: 100%;
padding: 3em;
box-sizing: border-box;
}
This is the interesting part, calculating the position of the content div. We are cropping the svg to the size of the image.
Note:
In our situation the calculations need to be made when the images are fully loaded, therefor we are using window load, which executes the code after all content is loaded on the page. If you are using jQuery 3+, and are running into issues, try using $(window).on('load', function () {};
$(window).load(function() {
$('.banner').each(function() {
var blockWidth = $('.banner .inner').width();
var blockHeight = $('.banner .inner').height();
var offsetLeft = $(".banner .wrap").offset().left;
var offsetTop = $(".banner .inner").position().top;
var offsetRight = parseInt(blockWidth) + parseInt(offsetLeft);
var offsetBottom = parseInt(blockHeight) + parseInt(offsetTop);
$('.blur').css({'clip': 'rect('+offsetTop+'px,'+offsetRight+'px,'+offsetBottom+'px,'+offsetLeft+'px)'});
});
});