Defined Edges With CSS3 Filter Blur
Asked Answered
L

17

106

I am blurring some images with this code

img {
  filter: blur(5px);
  -webkit-filter: blur(5px);
  -moz-filter: blur(5px);
  -o-filter: blur(5px);
  -ms-filter: blur(5px);
}

The edges of the image get blurred too though. Is it possible to blur the image, while keeping the edges defined? Like an inset blur or something?

Louvre answered 1/9, 2012 at 2:0 Comment(1)
You can add a filter to remove transparency after the blurRentschler
S
126

You could put it in a <div> with overflow: hidden; and set the <img> to margin: -5px -10px -10px -5px;.

Demo: jsFiddle

Output

CSS

img {
    filter: blur(5px);
        -webkit-filter: blur(5px);
        -moz-filter: blur(5px);
        -o-filter: blur(5px);
        -ms-filter: blur(5px);
    margin: -5px -10px -10px -5px;
}

div {
    overflow: hidden;
}
​

HTML

<div><img src="http://placekitten.com/300" />​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​</div>​​​​​​​​​​​​
Seafarer answered 1/9, 2012 at 2:6 Comment(12)
I just wrapped the img in a div with overflow:hidden and it worked. How is this possible?Louvre
@Moppy That doesn't work in Chrome 23/OS X for me. I think the margin is required.Seafarer
I don't understand how a div with overflow:hidden can help define the edges though?Louvre
@Moppy Because the img is inside the div and it's blur is overflowing the boundaries of the div. The overflow: hidden; cuts it off.Seafarer
What's with the junk at the bottom of the JSFiddle? I don't see why GA tracking a JSFiddle is necessary...Inosculate
@Bojangles, the "junk" at the bottom of the picture in the jsfiddle is in the image itself.Apply
Is there a way to do this for a background image? The idea is to create a blurred background image with text on itIonium
This was my approach as well, but in some cases the negative offsets were broken by adjacent elements. Setting z-index to a slightly higher level resolved the issue.Deflective
This no longer works for me, OS X - El Capitan on Chrome or Safari (both latest versions).Evelineevelinn
Works in Chrome, not in FirefoxNumbles
Works in chrome and safari on macos Sierra. No need to set the negative margins. Just overflow:hidden for the parent div is all that is required.Epideictic
Note that placekitten no longer works, which is why the image doesn't show in the JSFiddle anymore - it's not an issue with the code.Dittany
C
70

I was able to make this work with the

transform: scale(1.03);

Property applied on the image. For some reason, on Chrome, the other solutions provided wouldn't work if there was any relatively positioned parent element.

Check http://jsfiddle.net/ud5ya7jt/

This way the image will be slightly zoomed in by 3% and the edges will be cropped which shouldn't be a problem on a blurred image anyway. It worked well in my case because I was using a high res image as a background. Good luck!

Careen answered 16/9, 2014 at 18:49 Comment(5)
this is nice and simple and adjustable. it works perfectly for my situation jsfiddle.net/ud5ya7jt/28 while some of the other solutions seem to fail now.Inviting
Thank you very much for this, is exactly what I was looking for :)Claudioclaudius
setting the parent with overflow: hidden will remove the scrollbars! thanks!Stirps
Such a simple solution!Ungodly
scale(1) does work but the 1.03 is so that we crop the image by 3% in order for the blurred edges to not be as easily noticeableHazeghi
A
20

I used -webkit-transform: translate3d(0, 0, 0); with overflow:hidden;.

DOM:

<div class="parent">
    <img class="child" src="http://placekitten.com/100" />
</div>

CSS:

.parent {
    width: 100px;
    height: 100px;
    overflow: hidden;
    -webkit-transform: translate3d(0, 0, 0);
}
.child {
    -webkit-filter: blur(10px);
}

DEMO: http://jsfiddle.net/DA5L4/18/

This technic works on Chrome34 and iOS7.1

Update

http://jsfiddle.net/DA5L4/50/

if you use latest version of Chrome, you don't need to use -webkit-transform: translate3d(0, 0, 0); hack. But it doesn't works on Safari(webkit).

Ange answered 29/4, 2014 at 16:21 Comment(2)
@Razvan Cercelaru really? what version of safari did you check my demo? It works in Mac Safari 7.Ange
Worked for me! Thanks! (Chromium 50.0.2661.86 (64-bit) OSX)Boulder
M
18

Up-to-date answer (2024)

Use backdrop-filter instead! It blurs just like filter but without any edges, and without any compromises like resizing or scaling the image.

.blurred::after {
  content: "";
  position: absolute;
  width: 100%;
  height: 100%;
  backdrop-filter: blur(10px); /* apply the blur */
  pointer-events: none; /* make the overlay click-through */
}

.blurred {
  position: relative;
  width: 500px;
  height: 300px;
  background: no-repeat center center;
  background-image: url('https://besthqwallpapers.com/Uploads/26-5-2019/94041/thumb2-tesla-model-x-2019-exterior-front-view-new-gray-model-x.jpg');
  background-size: cover;
}
<div class="blurred"></div>

Keep in mind that this is not supported in IE and it only works in firefox if it is explicitly enabled.

Methanol answered 17/9, 2021 at 7:4 Comment(2)
This is the correct way to do if you can have an ::after element.Jecon
This needs another element to cover up the image, as <img> (and other replaced elements) cannot have pseudo :after selector. Works perfectly when the markup is right.Etty
R
16

You can also keep the whole video, you do not have to cut something away.
You can overlay inset shadows over the white-blurred edges.

This looks really nice as well :)

Just paste this code to your videos' parent:

.parent {
    -webkit-box-shadow: inset 0 0 200px #000000;
       -moz-box-shadow: inset 0 0 200px #000000;
            box-shadow: inset 0 0 200px #000000;
}
Ride answered 21/7, 2014 at 19:53 Comment(2)
Works a treat, none of the other suggestions helped.Sparhawk
In my case, it helped, but it was still leaving some undesired blur, so I added an extra box shadow layer: box-shadow: inset 0 0 200px #000000, inset 0 0 200px #000000;Steelman
M
9

In the many situations where the IMG can be made position:absolute, you can use clip to hide the blurred edges--and the outer DIV is unnecessary.

img {
    filter: blur(5px);
        -webkit-filter: blur(5px);
        -moz-filter: blur(5px);
        -o-filter: blur(5px);
        -ms-filter: blur(5px);
    position: absolute;
    clip: rect(5px,295px,295px;5px);
}
Mindamindanao answered 16/2, 2013 at 4:0 Comment(1)
caniuse.com/#feat=css-clip-path here the browser support for clipping. IE is the best 😆Prologize
E
7

Having tackled this same problem myself today, I'd like to present a solution that (currently) works on the major browsers. Some of the other answers on this page did work once, but recent updates, whether it be browser or OS, have voided most/all of these answers.

The key is to place the image in a container, and to transform:scale that container out of it's overflow:hidden parent. Then, the blur gets applied to the img inside the container, instead of on the container itself.

Working Fiddle: https://jsfiddle.net/x2c6txk2/

HTML

<div class="container">
    <div class="img-holder">
        <img src="https://unsplash.it/500/300/?random">
    </div>
</div>

CSS

.container {
    width    : 90%;
    height   : 400px;
    margin   : 50px 5%;
    overflow : hidden;
    position : relative;
}

.img-holder {
    position  : absolute;
    left      : 0;
    top       : 0;
    bottom    : 0;
    right     : 0;
    transform : scale(1.2, 1.2);
}

.img-holder img {
    width          : 100%;
    height         : 100%;
    -webkit-filter : blur(15px);
    -moz-filter    : blur(15px);
    filter         : blur(15px);
}
Evelineevelinn answered 24/2, 2016 at 15:1 Comment(1)
most aesthetically pleasing css code i've seen yet!Faintheart
B
5

Insert the image inside a with position: relative; and overflow: hidden;

HTML

<div><img src="#"></div>

CSS

div {
    position: relative;
    overflow: hidden;
}
img {
    filter: blur(5px);
        -webkit-filter: blur(5px);
        -moz-filter: blur(5px);
        -o-filter: blur(5px);
        -ms-filter: blur(5px);
}

This also works on variable sizes elements, like dynamic div's.

Brunn answered 18/10, 2013 at 6:22 Comment(0)
G
4

Just some hint to that accepted answer, if you are using position absolute, negative margins will not work, but you can still set the top, bottom, left and right to a negative value, and make the parent element overflow hidden.

The answer about adding clip to position absolute image has a problem if you don't know the image size.

Garrott answered 25/1, 2015 at 8:46 Comment(0)
U
3

You can clip the image or the container, that way you can make sure nothing with overflow it.

div {
  clip-path=polygon(0 0,100% 0, 100% 100%, 0 100%);
}

You can apply it to the image or you can use path or inset instead of polygon

Unicameral answered 21/2, 2023 at 9:6 Comment(2)
This is the best solution since it doesn't require wrapping the image in a div or an ::after pseudo-element. I use clip-path: inset(0); since it's more readable.Varini
Agreed. Best solution when working with images without a wrapper. To preserve the border-radius use clip-path: inset(0 round 4px)Leblanc
K
2

You can stop the image from overlapping it's edges by clipping the image and applying a wrapper element which sets the blur effect to 0 pixels. This is how it looks like:

HTML

<div id="wrapper">
  <div id="image"></div>
</div>

CSS

#wrapper {
  width: 1024px;
  height: 768px;

  border: 1px solid black;

  // 'blur(0px)' will prevent the wrapped image
  // from overlapping the border
  -webkit-filter: blur(0px);
  -moz-filter: blur(0px);
  -ms-filter: blur(0px);
  filter: blur(0px);
}

#wrapper #image {
  width: 1024px;
  height: 768px;

  background-image: url("../images/cats.jpg");
  background-size: cover;

  -webkit-filter: blur(10px);
  -moz-filter: blur(10px);
  -ms-filter: blur(10px);
  filter: blur(10px);

  // Position 'absolute' is needed for clipping
  position: absolute;
  clip: rect(0px, 1024px, 768px, 0px);
}
Kidney answered 8/7, 2014 at 12:31 Comment(0)
U
2

The simplest way is just adding a transparent border to the div that contains the image and setting its display property to inline-block just like this:

CSS:

div{
margin: 2rem;
height: 100vh;
overflow: hidden;
display: inline-block;
border: 1px solid #00000000;
}

img {
-webkit-filter: blur(2rem);
filter: blur(2rem);
}

HTML

<div><img src='https://images.unsplash.com/photo-1557853197-aefb550b6fdc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=375&q=80' /></div>

Here's a codepen depicting the same: https://codepen.io/arnavozil/pen/ExPYKNZ

Unscreened answered 1/6, 2020 at 7:39 Comment(0)
R
1

If you are using background image, the best way I found is:

filter: blur(5px);
margin-top: -5px;
padding-bottom: 10px;
margin-left: -5px;
padding-right: 10px;
Robeson answered 8/10, 2015 at 7:5 Comment(1)
This is actually a clever solution. I made that with percentage and added ie: width: 105%;Replacement
C
0

If all fails, You can choose to block this issue with a box-shadow effect.

Here's an example based on the question:

img {
  filter: blur(5px);
  -webkit-filter: blur(5px);
  -moz-filter: blur(5px);
  -o-filter: blur(5px);
  -ms-filter: blur(5px);

  box-shadow: 0 0 5px 20px #333; // <= Or colour you like.
}

This is of course not the most pleasant solution, but it should work great in some cases.

Chinn answered 8/6, 2022 at 18:13 Comment(0)
P
-1

You can try adding the border on an other element:

DOM:

<div><img src="#" /></div>

CSS:

div {
   border: 1px solid black;
}
img {
    filter: blur(5px);
}
Preconize answered 1/9, 2012 at 2:5 Comment(0)
M
-1

I found that, in my case, I did not have to add a wrapper.

I just added -

margin: -1px;

or

margin: 1px; // any non-zero margin
overflow: hidden;

My blurred element was absolutely positioned.

Mimir answered 5/11, 2014 at 22:5 Comment(1)
volkerotto.net/2014/07/03/…Yseult
B
-2

Here is a solution I came up with keeps 100% of the image and no crop is needed:

Basically I mirror tile the image in 3x3 grid then blur everything and then zoom in at the center image effectively creating like a repeat edges when blurring in after effects, it a bit strange that css3 don't have like a repeat edges built in.

Link to the method / code: How to blur an image using CSS3 without cropping or fading the edges?

Boltonia answered 2/10, 2015 at 8:31 Comment(2)
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes.Emetic
Well yeah funny that you say that cause I just updated that post and title and that totally messed up the link here x)Copeck

© 2022 - 2024 — McMap. All rights reserved.