CSS3滤镜模糊边缘定义

我用这个代码模糊了一些图像

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

不过图像的边缘也变得模糊了。有没有可能在保持边缘清晰的同时模糊图像?像是插入模糊还是什么?

124851 次浏览

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);
}

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>​​​​​​​​​​​​

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);
}

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.

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).

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);
}

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;
}

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!

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.

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.

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?

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;

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);
}

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

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.

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.