Emboss linked images with box-shadow and pseudo elements


This post was inspired by an article by Nathan Brown called PNG Masking: How to Dynamically Shape Any Image on Your Website.

The method described relied entirely on the use of pngs to mask images - I wanted to take it one step further and see how much I could get away with without using images to create a similar effect.

View Demo

The idea is to take a linked image, and clip the edges so that it forms a circle, and then create an embossed effect ontop of the image.

View in Firefox for the transition effect.

<a class="emboss" href="#"><img src="your-image.png" alt="" /></a>

.emboss, .emboss img, .emboss:before, .emboss:after { border-radius: 50% 50%;}

.emboss {
  position: relative;
  display: block;
  background: #FFF;
  width: 200px;
  height: 200px;
  margin: 0 auto;

.emboss img {
  width: 100%;
  height: 100%; /* prevent image from extending outside bounds of container */
  border: 0; /* remove border on IE9 */

.emboss:before, .emboss:after {
  position: absolute;
  content: "";
  transition: background-color 200ms ease-in;

.emboss:before {
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  box-shadow: inset 0 0 15px 1px hsla(0, 0%, 0%, .8);

.emboss:after {
  top: 7%;
  right: 7%;
  left: 7%;
  bottom: 7%;
  box-shadow: inset 0 0 25px hsla(0, 0%, 0%, .35);

.emboss:hover:before { background-color: hsla(0, 0%, 0%, .05);} 

.emboss:hover:after { background-color: hsla(0, 0%, 0%, .02);}

1. Make the anchor, image, and anchor pseudo elements circular using border-radius: 50% 50%;.

2. Make the anchor block level, set an explicit width and height, and ensure the image does not exceed its container's boundary by setting its width and height to 100%.

3. Set the pseudo-elements to be absolutely positioned relative to the corners of their parent. I set :before to be on the edge of the anchor, while :after to be slightly further in. (Using percentages will allow you to change the size of the parent without having to change the pseudo-elements' values).

4. Apply a hover effect on the background-color property of the pseudo-elements.


Due to the width and height enforced on the img tag, your image will have to have 1:1 dimensions to prevent it from being stretched or skewed - this technique can not clip your image within the bounds of the anchor.

There is a transition I've placed on the hover which works very nicely in Firefox, but works only in firefox right now.

Opera 11.5 doesn't apply border-radius to the image, and applying overflow: hidden; to the container doesn't have any effect.

Only IE9+ supports this technique, so using images for legacy versions is recommended. Nathan Brown's technique would be sufficient here.

This technique requires a container for the image, since there are discrepancies with box-shadow being applied directly to img tags, as well as the W3C spec currently not defining pseudo-elements on the img tag:

Note. This specification does not fully define the interaction of :before and :after with replaced elements (such as IMG in HTML). This will be defined in more detail in a future specification.

Hopefully some of these issues will be ironed out as browsers implement more of the CSS3 specifications!

No Responses

rss feed

This comment thread is closed. Got something important to say? contact us!