Creating Frosted Blur Transparent Modal Popup with CSS and JS
June 29, 2014 3:34 pm Leave your thoughtsI’ve been experimenting with a couple designs lately, many of which involves creating a floating centered modal popup with frosted blur effect. That is, a modal popup that overlays a full screen background image and blurring the background. The screenshots below will speak for themselves.
Can we do it with pure CSS only?
The short answer at the moment is no at the time of this writing. I have been trying different pure CSS techniques but was unable to achieve what I want. In the end I settle with CSS + jQuery technique.
The concept
CSS filter blurring is handy, but it is only able to blur the elements inside the element with blur filter CSS, not the things that it overlays. So if you have a DIV element called blurModal and we apply CSS blur to that DIV; anything inside the DIV will be blurred but anything outside even things underneath that element will not be blurred. You’ll end up with a modal box with blurred content overlaid on sharp background. Not exactly what we want for this exercise.
Therefore what we want to do is to create a pseudo-blurred modal popup. I said pseudo because the modal popup won’t actually blur the real background. Take a look at the sketch below to illustrate the page structure.
The idea is for the background and the modal to have their own background images, while maintaining the zoom level and the positioning between the two. So what we are doing is not overlaying the main background causing it to blur.
The Codes
So let’s get down to coding. This is probably the easiest way to show you and hopefully you’ll be able to practice what you know after this.
HTML
The HTML is quite simple, basically you have the wrapper which will hold the entire fullscreen background. Modal is the enclosing DIV to hold our modal popup information. This DIV will not hold the actual background image, because if we then blur it then everything inside this DIV including the text messages and all will be blurred. If you look at the code further, the “blurrer” DIV is the one that will be used to hold the “inset” blurred image. Lastly the “message” DIV is the one that will hold the text message, the “row” DIV is mostly for vertical alignment layout.
CSS
This page’s CSS is where things must be done properly. Firstly we set the html and body height to 100%, it’s not really required most of the time but I find with JSBin I have to do this perhaps because it’s displayed in a frame. One of the most important rules here is to set the .wrapper background image position to top left so that the image always start at the same position.
In relation to this rule, we also set the .modal .blurrer DIV background position to the same position as well, this is so that the blurred background position ends up at the correct position too. This is so that we don’t show a completely different location in the modal popup with the main background image.
Furthermore, we also set the .modal .blurrer position as absolute, to start at the top left corner, the z-index is set to 10 so that it’s lower than the .modal .message DIV z-index of 20. This means the message will always be on top of the background DIV.
JavaScript
This is where the magic happens. First things first, I have enclosed most the of the resizing logic in a javascript object called backgroundResizerBlurrer, this is just to separate things out a bit and avoid possible namespacing issue. Let’s start from the top, which is the ready stage. The first thing that we do is set the image aspect ratio by calling backgroundResizerBlurrer.setImageAspectRatio(), this is required so that we can determine later whether we want to stretch out the width or the height of the background. Otherwise we will end up with non-fullscreen background. The aspect ratio calculation is basically the width of the image divided by the height. In this example we know the background size is 2560px by 1600px.
Continuing on, we then setup an event handler to fire the refreshBackground() function everytime the window size changed. Again this is so that we have constant fullscreen background even if the user resizes their browser. The refreshBackground() function is where all the resizing happens. This function resizes both the main background image and the background image of the inset.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
if (this.imageAspectRatio < currentWindowAspectRatio) { $(".wrapper").css({ 'background-size': windowWidth + 'px' + ' auto ' }); $(".modal .blurrer").css({ 'background-size': windowWidth + 'px' + ' auto ' }); } else { //otherwise we adjust the height $(".wrapper").css({ 'background-size': ' auto ' + windowHeight + 'px' }); $(".modal .blurrer").css({ 'background-size': ' auto ' + windowHeight + 'px' }); } |
If the image’s aspect ratio is smaller than the current window’s aspect ratio, then we adjust the background’s width for both of the modal and the main background. This means that if we stretch out the background image’s width, the height of the image will naturally cover the entire viewport. The reverse also applies where the image aspect ratio is higher than the current window’s aspect ratio, which means that we priorities on covering the height of the viewport.
1 2 3 4 |
var modalPos = $(".modal").offset(); $(".modal .blurrer").css({ 'background-position': "-" + modalPos.left + 'px' + " -" + modalPos.top + 'px' }); |
Lastly, we also make sure that the background image’s position of the modal popup is adjusted. We almost have to imagine that we need to move the modal popup’s background back to the top left position of the viewport. To do this, we find out the current position of the modal popup and adjust the position of the background accordingly. In a nutshell it’s moving the background to the left and to the top of the modal enclosure.
Result
So after all the short CSS and JavaScript above, here is the actual result. It’s pretty cool that we have the modal popup with frosted blur background.
Update: An implementation example is the special quotes page.
Tags: css, design, web designCategorised in: CSS, jQuery, Web Design