Previously I wrote two tutorials on how to style the image element with CSS3 inset box-shadow and border-radius. The trick is to wrap the image with a span tag and apply the image as background-image. However, I recently ran into a problem with that trick while designing the PhotoTouch theme. The issue is that the background-image is not resizable and thus it is not a good idea to use in responsive design. Fortunately, I found a workaround to resolve this. So today I'm going to revisit this topic again.

View Demo Image Styles

Problem

Most browsers don't render the border-radius and inset box-shadow perfectly on the image element. This means you can't make the image look like embossed, glossy, pressed, etc.

border-radius problem

Previous Solution (see previous demo)

As I posted before, you can work around by applying the actual image as background-image.

code

Problem With Background-Image

Now the problem with using the background-image trick is that the image can not be resized dynamically. So it is not a good idea to use with responsive design where the images have to be resizable. This was an actual problem I encountered while designing the PhotoTouch theme for Themify.

New Solution!! (see demo)

Then later I found another workaround using a similar trick. Instead of applying the image as background-image, I found that I can achieve the same result by applying the CSS3 effects on the overlaying image wrap :after pseudo element. The best thing about this trick is the image remained intact and resizable.

Dynamic jQuery

Again, jQuery is used to add a dynamic wrap to the target images. The jQuery function below looks for all images in the #demo container and wraps it with a span tag.


<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){

	$('#demo img').each(function() {
		var imgClass = $(this).attr('class');
		$(this).wrap('<span class="image-wrap ' + imgClass + '" style="width: auto; height: auto;"/>');
		$(this).removeAttr('class');
	});

});
</script>

Output

The above code will output the following HTML code:


<span class="image-wrap " style="width: auto; height: auto;">
	<img src="image.jpg">
</span>

The CSS Trick (see demo)

The CSS trick is very simple. The overlaying effects are applied to the .image-wrap:after pseudo element. Border-radius (rounded corners) is applied on both the image and image-wrap:after element to match the style.

screenshot

CSS


.image-wrap {
	position: relative;
	display: inline-block;
	max-width: 100%;
	vertical-align: bottom;
}
.image-wrap:after {
	content: ' ';
	width: 100%;
	height: 100%;
	position: absolute;
	top: -1px;
	left: -1px;
	border: solid 1px #1b1b1b;

	-wekbit-box-shadow: inset 0 0 1px rgba(255,255,255,.4), inset 0 1px 0 rgba(255,255,255,.4), 0 1px 2px rgba(0,0,0,.3);
	-moz-box-shadow: inset 0 0 1px rgba(255,255,255,.4), inset 0 1px 0 rgba(255,255,255,.4), 0 1px 2px rgba(0,0,0,.3);
	box-shadow: inset 0 0 1px rgba(255,255,255,.4), inset 0 1px 0 rgba(255,255,255,.4), 0 1px 2px rgba(0,0,0,.3);

	-webkit-border-radius: 7px;
	-moz-border-radius: 7px;
	border-radius: 7px;
}

.image-wrap img {
	vertical-align: bottom;

	-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.4);
	-moz-box-shadow: 0 1px 2px rgba(0,0,0,.4);
	box-shadow: 0 1px 2px rgba(0,0,0,.4);

	-webkit-border-radius: 6px;
	-moz-border-radius: 6px;
	border-radius: 6px;
}

Image Styles

Various styles such as embossed, cutout / pressed, and glossy effect can be achieved using multiple inset box-shadows. You can also use the :before element to another layer of effect such as glossy gradient. See the demo source code for CSS details. Resize your browser window to see the resizable images.

screenshot

Browser Support

This trick works with most modern browsers such as Chrome, Firefox, Safari, and IE9+. Technically, it works with any browser that supports Javascript and CSS3.