Adding Vignettes to Images with CSS

Please note: This post was written 5 years ago, which is an age in programming terms, so please don't treat this as gospel! I'll be updating all posts soon enough, but if you'd especially like this one to be updated let me know.

This has nothing to do with cheese

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.

***

If you found this particularly useful and want to share the ♥ you can donate here.

***

1 Response

  1. 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 🙂

    Reply


~ Comments are now closed ~

Get in touch here