34

Is it possible to use -webkit-filter: blur(); on background-image?

I have tried this code and it just blurs everything but the background-image:

body {
  background-image: url('http://www.publicdomainpictures.net/pictures/10000/velka/pebbles-and-sea-11284647414Rbeh.jpg');
  background-attachment: fixed;
  -webkit-filter: blur(5px);
}

I have been searching for a while but cannot find anyone resources describing how to do this.

Elijah Lynn
  • 12,272
  • 10
  • 61
  • 91

3 Answers3

48

FUTURE USERS: This is not supported in IE7, IE8, IE9, IE10, IE11 or the current version of EDGE.

DO NOT USE on a real site, unless you have a fallback.

If you're looking for a solution that doesn't rely on extra markup, you could apply the background image and filter to a pseudo element on the body.

body {
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
    height: 100%;
}
body:before {
    content: "";
    position: absolute;
    background: url(http://lorempixel.com/420/255);
    background-size: cover;
    z-index: -1; /* Keep the background behind the content */
    height: 20%; width: 20%; /* Using Glen Maddern's trick /via @mente */

    /* don't forget to use the prefixes you need */
    transform: scale(5);
    transform-origin: top left;
    filter: blur(2px);
}

Check it out this JsFiddle.

M H
  • 2,179
  • 25
  • 50
JuanOjeda
  • 864
  • 7
  • 11
  • 1
    Works if you don't care about IE7 or earlier support. – Rick Calder Nov 26 '13 at 17:15
  • 11
    @RickCalder Seriously? It's about Webkit filter, even IE11 doesn't support it. – Hashem Qolami Sep 01 '14 at 08:43
  • 1
    I don't think the smaller width/height and then the transform is necessary. It is useful when using full-screen GIFs, because the canvas has to be re-painted every frame, but seeing a single frame image being used as the background, that should not pose any major CPU problems. If any gains are made with a single frame image, they ought to be minimal - though I haven't tested this. – Bram Vanroy Jan 22 '15 at 20:07
  • 1
    Edge 14 now supports filter. – Okku Sep 08 '16 at 15:12
21

Don't apply it to the body, apply it to a full size container as below, set the container size and position to absolute and then the rest of the content to relative and set the z-indexes.

​<body>
<div class="bgImageContainer">
</div>
<div class="content"> Some text and stuff here</div>
</body>​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​
.bgImageContainer{
    background-image:url('http://www.whitegadget.com/attachments/pc-wallpapers/16950d1224057972-landscape-wallpaper-blue-river-scenery-wallpapers.jpg'); 
    width:500px;
    height:400px;
    -webkit-filter: blur(5px);
    z-index:0;
    position:absolute;
}
.content{
    z-index:10;
    position:relative;
}

Edit - Updated the fiddle, the old image wasn't working any more.

http://jsfiddle.net/Yr2zD/1130/

Rick Calder
  • 18,310
  • 3
  • 24
  • 41
  • This works but isn't pretty, I was hoping for a simpler way. Thanks for sharing this! – Elijah Lynn Oct 31 '12 at 22:32
  • 1
    Has anyone tried to do this with a full screen background image .. there is a serious reduction in Chrome performance. – smoizs Jun 26 '13 at 10:10
  • @smoizs it can be solved by making it 20% and scaling out to 100% of the width. [Original idea](https://medium.com/what-i-learned-building/4364221d6d97) comes from Glen Maddern – mente Jul 10 '13 at 07:19
  • Rick Calder's solution is good, only add transform: translate3d(0,0,0) to make it smoother. Making it 20% and scaling out to 100% of the width does not produce good results. – Razvan Cercelaru Jul 20 '13 at 18:15
  • Interesting that over a year after this answer was given all of a sudden it's getting down voted and un upvoted lol. The new chosen answer is good, but it doesn't cover IE before version 8. – Rick Calder Nov 26 '13 at 23:47
  • 1
    This approach causes a HUGE performance impact on Android browsers due to the paint operation taking longer for every object over the background – NicolasZ Apr 29 '15 at 21:35
  • 1
    Downvoting a 2 year old answer because it doesn't work well on current browsers for the win.... – Rick Calder Apr 30 '15 at 14:15
  • 1
    Not working where? Works just fine in Chrome. The image in the fiddle wasn't working, but the code still was. Updated the fiddle with a new image. @Dev_Man – Rick Calder Oct 24 '17 at 14:08
4

If background for the full page then this is the best solution for me.

body {
    //background-color: black;  use it if you don't want the background border
}
body:before {
    content: '';
    position: fixed;
    width: 100vw;
    height: 100vh;
    background-image: url('http://www.publicdomainpictures.net/pictures/10000/velka/pebbles-and-sea-11284647414Rbeh.jpg'); // your image
    background-position: center center;
    background-repeat: no-repeat;
    background-position: 100% 100%;
    background-size: cover;
    filter: blur(2px);
    z-index: -9;
}
Md Imran Choudhury
  • 9,343
  • 4
  • 62
  • 60
  • 2
    This is a great answer! Thanks. Although why is there a border? -- edit I got the answer, this is all because of blur(). One may use transform: scale(1.1); to remove the border https://stackoverflow.com/questions/28870932/how-to-remove-white-border-from-blur-background-image – tomsihap Feb 02 '18 at 15:55