Adding Vignettes to Images with CSS

Vignettes are something we’ve been able to add to images in Photoshop for many years – it describes the technique of reducing clarity towards the edges of images by reducing things like saturation and brightness, and can often give an image a different quality. It was for that reason that I decided I wanted to use them in my designs, but I certainly didn’t want to use images that were pre-composed with the effect, and so decided it would be simple to add them using CSS. What I didn’t know, was that there were many things conspiring to prevent me achieving the effect properly. So without further adieu, allow me to share my experience with you.

I first read Trent Walton’s article on vignetting and implemented that on the site, but soon realised its shortcomings. Firstly the use of negative z-indexing played havoc with my backgrounds – this is because its fine if you have an all-white background, but if you have an image, it simply throws the picture behind it. And secondly I found myself frustrated with the fact that you couldn’t right click and save the image with ease. I also took a look at Chris Coyier’s article on the subject, but once again hit a brick wall.

So after a lot of playing around and many alterations I came up with a solution that is the combination of many techniques that I have come across, and the one use on the site today.

My HTML is as follows.

<figure>	
    <img src="path/to/image" alt="Test image" />
</figure>

The class of left simply floats the element to the left, while I use the following CSS to style the rest.

figure {
	position: relative;
	display: block; 
}

	figure.vignette img {
		z-index: 1;
		position: relative;
		display: block;
	}

	figure::before {
		content: "";
		position: absolute;
		top: -1em;
		bottom: -1em;
		left: -1em;
		right: -1em;
	}

	figure.vignette::after {
		position: absolute;
		top: 0;
		bottom: 0;
		left: 0;
		right: 0;
		content: "";
		z-index: 2;
		pointer-events: none;
		width:100%;
		height:100%;
		box-shadow:inset 0px 0px 85px rgba(0,0,0,.5);
		-webkit-box-shadow:inset 0px 0px 85px rgba(0,0,0,.5);
		-moz-box-shadow:inset 0px 0px 85px rgba(0,0,0,.5);
		border-radius: 3px;
		-moz-border-radius: 3px;
		-webkit-border-radius: 3px;
	}

So the main styling of the figure element simply makes sure it is visible and sets it’s position to relative, as does the styling of the image within it; but it is the code that follows that does all the magic. We use the pseudo ::before and ::after to apply the vignette effect. If you are unfamiliar with those selectors, visit W3’s article on the subject. You can increase the intensity of the vignette by altering the box-shadow property to have a less transparent shadow, or bigger radius. You could even have different colours by altering the same property.

And that’s it! I haven’t found any inherent problems with this technique just yet, and although this method isn’t really apply a vignette in the traditional sense, I feel it does a pretty good imitation of it.


Posted

in

by

Comments

One response to “Adding Vignettes to Images with CSS”

  1. Dan avatar
    Dan

    That’s awesome 🙂
    I turned this into a .LESS mix-in so all I had to write was .VIN; in my less style sheet to add vignettes to images 🙂