I am having trouble applying a blur effect on a semi-transparent overlay div. I'd like everything behind the div the be blurred, like this:
Here is a jsfiddle which doesn't work: http://jsfiddle.net/u2y2091z/
Any ideas how to make this work? I'd like to keep this as uncomplicated as possible and have it be cross-browser. Here is the CSS I'm using:
#overlay {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background:black;
background:rgba(0,0,0,0.8);
filter:blur(4px);
-o-filter:blur(4px);
-ms-filter:blur(4px);
-moz-filter:blur(4px);
-webkit-filter:blur(4px);
}
This question is related to
html
css
blur
css-filters
If you're looking for a reliable cross-browser approach today, you won't find a great one. The best option you have is to create two images (this could be automated in some environments), and arrange them such that one overlays the other. I've created a simple example below:
<figure class="js">
<img src="http://i.imgur.com/3oenmve.png" />
<img src="http://i.imgur.com/3oenmve.png?1" class="blur" />
</figure>
figure.js {
position: relative;
width: 250px; height: 250px;
}
figure.js .blur {
top: 0; left: 0;
position: absolute;
clip: rect( 0, 250px, 125px, 0 );
}
Though effective, even this approach isn't necessarily ideal. That being said, it does yield the desired result.
Here's a solution that works with fixed backgrounds, if you have a fixed background and you have some overlayed elements and you need blured backgrounds for them, this solution works:
Image we have this simple HTML:
<body> <!-- or any wrapper -->
<div class="content">Some Texts</div>
</body>
A fixed background for <body>
or the wrapper element:
body {
background-image: url(http://placeimg.com/640/360/any);
background-size: cover;
background-repeat: no-repeat;
background-attachment: fixed;
}
And here for example we have a overlayed element with a white transparent background:
.content {
background-color: rgba(255, 255, 255, 0.3);
position: relative;
}
Now we need to use the exact same background image of our wrapper for our overlay elements too, i use it as a :before
psuedo-class:
.content:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
filter: blur(5px);
background-image: url(http://placeimg.com/640/360/any);
background-size: cover;
background-repeat: no-repeat;
background-attachment: fixed;
}
Since the fixed background works in a same way in both wrapper and overlayed elements, we have the background in exactly same scroll position of the overlayed element and we can simply blur it. Here's a working fiddle, tested in Firefox, Chrome, Opera and Edge: https://jsfiddle.net/0vL2rc4d/
NOTE: In firefox there's a bug that makes screen flicker when scrolling and there are fixed blurred backgrounds. if there's any fix, let me know
background: rgba(255,255,255,0.5);
backdrop-filter: blur(5px);
Instead of adding another blur background to your content, you can use backdrop-filter. FYI IE 11 and Firefox may not support it. Check caniuse.
Demo:
header {_x000D_
position: fixed;_x000D_
width: 100%;_x000D_
padding: 10px;_x000D_
background: rgba(255,255,255,0.5);_x000D_
backdrop-filter: blur(5px);_x000D_
}_x000D_
body {_x000D_
margin: 0;_x000D_
}
_x000D_
<header>_x000D_
Header_x000D_
</header>_x000D_
<div>_x000D_
<img src="https://dummyimage.com/600x400/000/fff" />_x000D_
<img src="https://dummyimage.com/600x400/000/fff" />_x000D_
<img src="https://dummyimage.com/600x400/000/fff" />_x000D_
</div>
_x000D_
From backdrop-filter
...apply graphical effects such as blurring or color shifting to the area behind an element. Because it applies to everything behind the element, to see the effect you must make the element or its background at least partially transparent.
For a more simple and up to date answer:
backdrop-filter: blur(6px);
Note browser support is not perfect but in most cases a blur would be non essential.
Here is an example that uses svg
filter.
The idea is to use an svg
element with height
same as the #overlay
and apply the feGaussianblur
filter on it. This filter is applied on an svg
image
element. To give it an extruded effect, you could use a box-shadow
at the bottom of the overlay.
Browser Support for svg
filters.
body {
background: #222222;
}
#container {
position: relative;
width: 450px;
margin: 0 auto;
}
img {
height: 300px;
}
#overlay {
position: absolute;
left: 0;
top: 0;
width: 100%;
z-index: 1;
color: rgba(130, 130, 130, 0.5);
font-size: 50px;
text-align: center;
line-height: 100px;
box-shadow: 0 3px 5px rgba(0, 0, 0, 0.3);
}
_x000D_
<div id="container">
<img src="http://lorempixel.com/450/300/sports" />
<div id="overlay">WET</div>
<svg width="450" height="100" viewBox="0 0 450 100" style="position: absolute; top: 0;">
<defs>
<filter id="blur">
<feGaussianBlur in="SourceGraphic" stdDeviation="3" />
</filter>
</defs>
<image filter="url(#blur)" xlink:href="http://lorempixel.com/450/300/sports" x="0" y="0" height="300px" width="450px" />
</svg>
</div>
_x000D_
Here's a possible solution.
HTML
<img id="source" src="http://www.byui.edu/images/agriculture-life-sciences/flower.jpg" />
<div id="crop">
<img id="overlay" src="http://www.byui.edu/images/agriculture-life-sciences/flower.jpg" />
</div>
CSS
#crop {
overflow: hidden;
position: absolute;
left: 100px;
top: 100px;
width: 450px;
height: 150px;
}
#overlay {
-webkit-filter:blur(4px);
filter:blur(4px);
width: 450px;
}
#source {
height: 300px;
width: auto;
position: absolute;
left: 100px;
top: 100px;
}
I know the CSS can be simplified and you probably should get rid of the ids. The idea here is to use a div as a cropping container and then apply blur on duplicate of the image. Fiddle
To make this work in Firefox, you would have to use SVG hack.
This will do the blur overlay over the content:
.blur {
display: block;
bottom: 0;
left: 0;
position: fixed;
right: 0;
top: 0;
-webkit-backdrop-filter: blur(15px);
backdrop-filter: blur(15px);
background-color: rgba(0, 0, 0, 0.5);
}
#bg, #search-bg {_x000D_
background-image: url('https://images.pexels.com/photos/719609/pexels-photo-719609.jpeg?w=940&h=650&auto=compress&cs=tinysrgb');_x000D_
background-repeat: no-repeat;_x000D_
background-size: 1080px auto;_x000D_
}_x000D_
_x000D_
#bg {_x000D_
background-position: center top;_x000D_
padding: 70px 90px 120px 90px;_x000D_
}_x000D_
_x000D_
#search-container {_x000D_
position: relative;_x000D_
}_x000D_
_x000D_
#search-bg {_x000D_
/* Absolutely position it, but stretch it to all four corners, then put it just behind #search's z-index */_x000D_
position: absolute;_x000D_
top: 0px;_x000D_
right: 0px;_x000D_
bottom: 0px;_x000D_
left: 0px;_x000D_
z-index: 99;_x000D_
_x000D_
/* Pull the background 70px higher to the same place as #bg's */_x000D_
background-position: center -70px;_x000D_
_x000D_
-webkit-filter: blur(10px);_x000D_
filter: url('/media/blur.svg#blur');_x000D_
filter: blur(10px);_x000D_
}_x000D_
_x000D_
#search {_x000D_
/* Put this on top of the blurred layer */_x000D_
position: relative;_x000D_
z-index: 100;_x000D_
padding: 20px;_x000D_
background: rgb(34,34,34); /* for IE */_x000D_
background: rgba(34,34,34,0.75);_x000D_
}_x000D_
_x000D_
@media (max-width: 600px ) {_x000D_
#bg { padding: 10px; }_x000D_
#search-bg { background-position: center -10px; }_x000D_
}_x000D_
_x000D_
#search h2, #search h5, #search h5 a { text-align: center; color: #fefefe; font-weight: normal; }_x000D_
#search h2 { margin-bottom: 50px }_x000D_
#search h5 { margin-top: 70px }
_x000D_
<div id="bg">_x000D_
<div id="search-container">_x000D_
<div id="search-bg"></div>_x000D_
<div id="search">_x000D_
<h2>Awesome</h2>_x000D_
<h5><a href="#">How it works ยป</a></h5>_x000D_
</div>_x000D_
</div>_x000D_
</div>
_x000D_
I came up with this solution.
Click to view image of blurry effect
It is kind of a trick which uses an absolutely positioned child div
, sets its background image same as the parent div
and then uses the background-attachment:fixed
CSS property together with the same background
properties set on the parent element.
Then you apply filter:blur(10px)
(or any value) on the child div.
*{
margin:0;
padding:0;
box-sizing: border-box;
}
.background{
position: relative;
width:100%;
height:100vh;
background-image:url('https://images.unsplash.com/photo-1547937414-009abc449011?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80');
background-size:cover;
background-position: center;
background-repeat:no-repeat;
}
.blur{
position: absolute;
top:0;
left:0;
width:50%;
height:100%;
background-image:url('https://images.unsplash.com/photo-1547937414-009abc449011?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80');
background-position: center;
background-repeat: no-repeat;
background-attachment: fixed;
background-size:cover;
filter:blur(10px);
transition:filter .5s ease;
backface-visibility: hidden;
}
.background:hover .blur{
filter:blur(0);
}
.text{
display: inline-block;
font-family: sans-serif;
color:white;
font-weight: 600;
text-align: center;
position: relative;
left:25%;
top:50%;
transform:translate(-50%,-50%);
}
_x000D_
<head>
<title>Blurry Effect</title>
</head>
<body>
<div class="background">
<div class="blur"></div>
<h1 class="text">This is the <br>blurry side</h1>
</div>
</body>
_x000D_
Source: Stackoverflow.com