101

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?

colmtuite
  • 4,311
  • 11
  • 45
  • 67
  • You can add a [filter to remove transparency](https://stackoverflow.com/a/72297563/13216566) after the blur – killovv May 19 '22 at 01:13

17 Answers17

124

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>​​​​​​​​​​​​
ThinkingStiff
  • 64,767
  • 30
  • 146
  • 239
69

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!

João Josézinho
  • 2,648
  • 4
  • 23
  • 27
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).

GeckoTang
  • 2,697
  • 1
  • 16
  • 18
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;
}
GlabbichRulz
  • 948
  • 9
  • 28
  • 2
    Works a treat, none of the other suggestions helped. – DGibbs Aug 11 '15 at 13:53
  • 3
    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;` – falsarella Feb 12 '16 at 19:23
13

Up-to-date answer (2021)

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.

W4G1
  • 1,337
  • 1
  • 11
  • 15
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);
}
genedronek
  • 107
  • 1
  • 2
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);
}
rorymorris89
  • 1,144
  • 7
  • 14
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.

Marc Audet
  • 46,011
  • 11
  • 63
  • 83
bpanatta
  • 509
  • 3
  • 12
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.

cn123h
  • 2,302
  • 1
  • 21
  • 16
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

Ardillo95
  • 61
  • 4
  • 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. – enriquejr99 Apr 21 '23 at 08:19
  • Agreed. Best solution when working with images without a wrapper. To preserve the border-radius use `clip-path: inset(0 round 4px)` – Mohamed Ramrami Aug 05 '23 at 09:58
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);
}
Benny Code
  • 51,456
  • 28
  • 233
  • 198
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

arnavpanwar99
  • 377
  • 2
  • 6
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;
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.

Prince Owen
  • 1,225
  • 12
  • 20
-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);
}
Krycke
  • 3,106
  • 1
  • 17
  • 21
-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.

brendangibson
  • 2,377
  • 2
  • 21
  • 36
-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?

Community
  • 1
  • 1
Patrik Fröhler
  • 1,221
  • 1
  • 11
  • 38
  • 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. – ArnonZ Oct 02 '15 at 14:01
  • Well yeah funny that you say that cause I just updated that post and title and that totally messed up the link here x) – Patrik Fröhler Oct 03 '15 at 08:48