How to create iOS Backdrop effect
CSS Backdrop filters create a fresh and modern design, but unfortunately they are only supported by Safari. Here is a list of the best techniques to get around this problem.
What is a backdrop filter ?
Backdrop filter is a CSS filter which allows to apply a filter (such as blur, hue, brightness…) to the backdrop of an element — instead on the element itself. Here is a demo with images :
This effect can be created easily with this simple CSS property :
-webkit-backdrop-filter: blur(10px);
Unfortunately, this cool property doesn’t have a very wide browser support. According to canIuse.com:
As you can see, this is currently only supported by Safari.
To solve this problem, and create this effect on other browsers, I looked for solutions on the wider net. During this process I found that there were plenty of clever solutions to overcome this problem. Here are the best results I found, classified according to usage and tools required.
1. Backdrop filter on a fixed body background:
The easiest way of creating a backdrop filter like effect is to apply it on a fixed full-height-width background image.
You can create already nice effects like these :
Main idea here :
- add a fixed background to the body tag
- prepend an absolutely positioned element to the ‘backdrop div’ (usually a ::before pseudo element)
- get the ::before element to inherit the body’s background
- add any filter to the ::before element
Under these conditions, the ::before element will apply the specified filter applied to its background image, which is displayed only ‘under’ the backdrop div.
Here is an excellent tutorial :
You can also have a look on this codePen:
Given these resources, you have to keep in mind that these codes will only work under these two conditions:
- having a fixed background
- applying this background to the body tag
2. Backdrop on any selected element:
Fixed background is great, especially for hero headers or log in pages. But you may want to use overlay on smaller surfaces, such as on a content images, or even on multiple elements (galleries, etc).
Here things become bit more tricky, because can’t use a fixed background defined by the size of the viewport. Fortunately, there are some Jquery plugins available which will do the job. Here are 2 I found:
If you don’t want to use Jquery, things can become a bit trickier. However, let’s have a look at it anyway!
a. Backdrop on the side of an element (on top, bottom, etc):
The original idea is fully inspired from this tutorial:
With this technique, you can get a result like this:
Here is my Pen for this example — I just modified the original code a bit to extend it for a more general use:
In a nutshell, the idea here is:
- to create a background element (here the unblurred photo), let’s call it element A
- to create un absolutely positioned element with same size than the background element (element B), and with overflow: hidden propriety
- append a ::before element to to element B, give to it the same background than element A and apply the selected filter (blur filter here)
- apply an Y translation to B to overlay A
- / here is the trick / apply a second Y translation to B’s ::before element for it to be exactly positioned on A. Since B’s overflow is hidden, only the part of the filtered background inside B will be visible, and, since the filtered background is positioned on A, it will visually adjust to A’s background.
Exemple:
On first photo, for the translation part, we did
.elementB {transform: translateY(-30%)}.elementB::before {transform: translateY(-70%)}
On the second photo:
.elementB {transform: translateY(-70%)}.elementB::before {transform: translateY(70%)}
b. Backdrop of any shape — svg only solution
If you need to completely get rid of constraints on your overlay, then the most flexible solution might be to use svg. One of the strengths of svg is that it has a broad browser support, especially for filters.
Here is an exemple of what you can do:
Here is the Pen for the above example:
The main idea is to :
- create a svg which will encompace the whole image to overlay
- create a first element (a <rect> element for example) with the image to overlay set as background (using a <pattern> element)
<defs><pattern id=”Pattern” width=”100%” height=”100%” x=”0" y=”0" patternUnits=”userSpaceOnUse”><image width=”100%” height=”100%” y=”-2" xlink:href=”tomme.png” patternUnits=”userSpaceOnUse”></image></pattern></defs><rect class=”background_rect” x=”0" y=”0" width=”100%” height=”100%” stroke=”rgba(250,250,250,0.3)” stroke-width=”0.1px” fill=”url(#Pattern)”></rect>
- create a second element, the ‘overlaying’ element, with the same image set as background, but this time with a filter applied (therefore, we also create a second <pattern> element):
<defs><filter id=”blurFilter” x=”0" y=”0"><feGaussianBlur stdDeviation=”0.5"></feGaussianBlur></filter><pattern id=”blurPattern” width=”100%” height=”100%” x=”0" y=”0" patternUnits=”userSpaceOnUse”><image width=”100%” height=”100%” y=”-2" xlink:href=”tomme.png” filter=”url(#blurFilter)”></image></pattern></defs><rect class=”overlay_rect” x=”12" y=”5" width=”35%” height=”83%” fill=”url(blurPattern)” rx=”1" ry=”1"></rect>
Nb: here it is very important to set the same attributes to the two <patterns> and <image>, and to add ‘ patternUnits=”userSpaceOnUse” ’ for the patterns to scale to the main svg (and not to the inner element they are linked to).
- then you just have to add content to the overlaying element, and to style it
c. Backdrop on videos (!) :
This part is fully credited to this excellent tutorial, which explains a very cool video backdrop effect :
The trick here is to superimpose two <video> elements (one of them being filtered), and then to aply the clip-path property to the unfiltered one.
Nb: this method is also very suitable with images, but has to be used carefully, because of browsers partial support (see below).
Browser limitations: Unfortunately, the clip-path property is still experimental, and in particular seems to still have partial support on Safari — this property have to be used cautiously.
Videos & Svg:
It would have been great to use Svg — which have a broad cross-browser support — on videos, but svg currently do not support the video element -actually they are supported, but as a <foreignObject> element, which makes things a bit more complicated.
3. Dynamic backdrop effect:
For those who want to get a dynamic backdrop effect — I mean, to get a backdrop not only on one defined element, but on any element of the page- then there is no other alternative than to go for javascript. For this, there are some excellent scripts available — here are the best solutions I found so far:
- This one uses the open source script html2canvas, which takes dynamic ‘screenshots’ of the content to blur:
https://jsfiddle.net/nallenscott/WtQjY/41/
- This excellent script only requires Jquery, and uses the clone() methode to append a copy of content to overlay to the bluring element:
Conclusion :
In the article above, I tried to gather the main ways in which to create iOS style backdrops on any browser. However, I am sure I missed some Please feel free to share your thoughts about this, in the comment section below. I would especially appreciate your insight on other techniques I may have overlooked.