Home » Html » Add circular fading opacity (vignette effect) to images in CSS

Add circular fading opacity (vignette effect) to images in CSS

Posted by: admin November 29, 2017 Leave a comment

Questions:

I want to give circular opacity to an image using CSS.

I know I can achieve opacity on images like this:

.circle img {
    opacity: 0.4;
    filter: alpha(opacity=40);
}

I know I can achieve circular images like this:

.circle {
    border-radius: 50%;
    display: inline-block;
}
.circle img {
    border-radius: 50%;
    display: block;
}

I want somehow to merge the two things above and apply the opacity only for the edges of the image, so the center of the image gets almost nothing from the opacity tag. I have searched for hours but found nothing.

Without opacity: http://jsfiddle.net/8w6szf84/47

With opacity: http://jsfiddle.net/8w6szf84/48/ -> bad opacity, want only the edges to fade…

Do I need to use Javascript on this? Any suggestions?

Answers:

Ok, so what we can do is create a :after element that will be equal to the size of the parent. Using this we can set a background gradient that will make it appear as the image is fading into the solid colour background.

Note: In this example I have made the gradient element a little bigger and moved it over 1px to stop a border from appearing around it. From here you can mess around to get the perfect effect that you want.

.circle {
    border-radius: 50%;
    display: inline-block;
    position: relative;
}
.circle img {
    border-radius: 50%;
    display: block;
    border:1px solid #fff;
}
.circle:after {
    content: "";
    display: block;
    width: 100%;
    height: 100%;
    background: radial-gradient(ellipse at center, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 70%,rgba(255,255,255,1) 100%);
    border-radius: 50%;
    position: absolute;
    top: 0; left: 0;
}
<div class="circle">
    <img src="http://placeimg.com/200/200/any" />
</div>

Edit: Here is another version without setting a height or width and getting rid of the border that gets caused if using 100% of parent. As Vucko pointed out we don’t need the negative values for the position but can use a border around the img instead.

JsFiddle Here

Questions:
Answers:

you can also use a box-shadow

.shadow {
  border-radius: 50%;
  display: inline-block;
  position: relative;
}
.shadow img {
  border-radius: 50%;
  display: block;
  border: 1px solid #fff;
}
.shadow:after {
  content: "";
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  position: absolute;
  top: 0;
  left: 0;
  box-shadow: inset 10px 24px 40px 0px white, 
    inset -10px -24px 40px 0px white, 
    inset 20px -10px 40px 0px white, 
    inset -20px 10px 40px 0px white;
}
<div class="shadow">
  <img src="http://placeimg.com/200/200/any" />
</div>

Questions:
Answers:

You could use two (of the same) images and have the top one smaller and transparent.

.circle-opaque {
    border-radius: 50%;          /* Make it a circle */
    display: inline-block;       
    position: absolute;          /* Able to position it, overlaying the other image */
    left:0px;                    /* Customise the position, but make sure it */
    top:0px;                     /* is the same as .circle-transparent */
    z-index: -1;                 /* Makes the image sit *behind* .circle-transparent */
}
.circle-opaque img {
    border-radius: 50%;          /* Make it a circle */
    z-index: -1;
}
.circle-transparent {
    border-radius: 50%;          /* Make it a circle */
    display: inline-block;       
    position: absolute;          /* Able to position it, overlaying the other image */
    left: 0px;                   /* Customise the position, but make sure it */
    top: 0px;                    /* is the same as .circle-transparent */
    z-index: 1;                  /* Makes the image sit *on top of* .circle-transparent */
}
.circle-transparent img {
    width: 200px;
    opacity: 0.4;                /* Make the second image transparent */
    filter: alpha(opacity=40);   /* For IE8 and earlier; optional */
    z-index: 1;                  /* And on top of the first */
}
<div class="circle-opaque">
    <img src="http://www.catchannel.com/images/articles/0805/orange-kitten-200px.jpg" />
</div>
<div class="circle-transparent">
    <img src="http://www.catchannel.com/images/articles/0805/orange-kitten-200px.jpg" />
</div>

http://jsfiddle.net/joe_young/20y832r7/

Questions:
Answers:

Here is a modified version of Ruddy’s answer except that the diameter of gradient matches the width (or height) of the image instead of diagonal. Border radius is not required. 80% of the image displays as-is, the remaining 20% fades from transparent to white.

.circle {
  display: inline-block;
  position: relative;
}
.circle img {
  display: block;
}
.circle:after {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background-image: radial-gradient(circle closest-side at center,
    rgba(255, 255, 255, 0) 0,
    rgba(255, 255, 255, 0) 80%, 
    rgba(255, 255, 255, 1) 100%
  );
}
<div class="circle">
  <img src="http://www.catchannel.com/images/articles/0805/orange-kitten-200px.jpg">
</div>

Note that radial gradients are drawn from the specified center; while box shadows are drawn from the edges; therefore both produce different results.

Questions:
Answers:

Although this approach isn’t as clean as others (possibly due to lack of time), I believe it could be cleaned up. However, it’s using just box shadows to achieve the look you’re thinking of. (Radial gradients would possibly be preferred, although if you need a fallback, this could be an option)

div {
  height: 300px;
  width: 300px;
  background: url(http://placekitten.com/g/300/400);
  border-radius: 50%;
  box-shadow: 
    inset -5px -5px 100px white, 
    inset 0 0 90px white, 
    inset 0 0 80px white, 
    inset 0 0 70px white, 
    inset 0 0 60px white, 
    inset 0 0 50px white, 
    inset 0 0 40px white, 
    inset 0 0 30px white, 
    inset 0 0 20px white, 
    inset 0 0 10px red; 
}
<div></div>

Questions:
Answers:

I like simple, so the following might suffice:

.circle {
  background-image: radial-gradient(ellipse at center center, rgba(0, 0, 0, 0) 0%, rgba(255, 255, 255, 1) 70%, rgba(255, 255, 255, 1) 100%);
  display: inline-block;
}
.circle img {
  border-radius: 50%;
  mix-blend-mode: lighten;
}
<div class="circle">
  <img src="http://www.catchannel.com/images/articles/0805/orange-kitten-200px.jpg" />
</div>