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.

98 Comments

1 3 4 5
  1. Alquiler yates Ibiza
    Jul 30, 2012 @ 3:19 am

    ’m having trouble aligning said image, if I align the image the :after stays where the image previously was

    Reply

  2. paul
    Aug 26, 2012 @ 10:03 am

    Thank you for this – and Iwas very hopeful that it would work – but clearly I am missing something! And I wonder if you could help?

    I have added the jQuery and this is correctly producing

    And I have these classes in the CSS

    .feather .image-wrap {
    position: relative;

    -webkit-border-radius: 30em;
    -moz-border-radius: 30em;
    border-radius: 30em;
    opacity: 0.25;
    }

    .feather .image-wrap:after {
    position: absolute;
    content: ‘ ‘;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;

    background: -webkit-gradient(radial, 50% 50%, 50, 50% 50%, 70, from(rgba(255,255,255,0)), to(rgba(255,255,255,1)));
    background: -moz-radial-gradient(50% 50%, circle, rgba(255,255,255,0) 50px, rgba(255,255,255,1) 70px);
    }

    I am looking for “feathered” edge to the image; and once I have got this working I would like to try and do it for a rectangular shape – any thoughts most welcome and thank you
    Paul

    Reply

  3. seo
    Aug 30, 2012 @ 3:04 am

    I am definitely using these tips in my current project! Thank you for this post.

    Reply

  4. Graphic Design Belfast
    Sep 8, 2012 @ 7:35 am

    Interesting approach. Border radius of an image on website design can be tricky especially when trying to create various effects. I like your solution here. The embossed edges are a fresh take on image design and layout for graphic design in websites.

    Reply

  5. Piotr
    Nov 21, 2012 @ 1:54 pm

    I am not a CSS pro but I’ve take what was the best and apply to my site:
    http://guistyles.com/index.php
    If someone can take a look, maybe i can clean code after that.. i think i leave to much of it :)
    Thx

    Reply

  6. D8Lab.com
    May 27, 2013 @ 4:18 pm

    Thanks for that. Bookmarked the page! nice one…

    Reply

1 3 4 5

Leave a Reply