CSS shadows are great to make things stand out, become more readable and give your designs a sense of depth. The problem is though that whilst text-shadow does only add a shadow to the letters, adding a box-shadow to an image will always show a rectangular shadow, regardless of the transparency of the image.

box shadow demo

You can work around that by using filter: drop-shadow() instead. This filter recognises the transparent parts of the image or the shape of the SVG path and applies the shadow accordingly.

drop shadow demo

You can see and the difference and play with it in this codepen:

codepen showing the difference between box shadow and drop shadow

There are two problems with this though. The first one is about developer tools. Chromium Developer tools show a nifty shadow editor when you use text-shadow or box-shadow:

dropshadow editor

This editor doesn’t get triggered by the filter yet. I filed a bug with Edge Devtools, so this might be remedied soon.

The second issue is when you want to do a rollover drop-shadow effect. With an SVG, you can apply the hover to the path to get the effect, but with an image you will always trigger the hover on the whole image, not exclusively on the parts that are visible.

I’ve written a workaround 13 years ago, that uses canvas to offer that functionality:

Irregular shape rollover demo page in action

  • When you roll over the image, the script copies it to a canvas and detects the colour at the current mouse position.
  • If the colour is not transparent, it adds a class called over to the image.
  • If it is not transparent it removes the class.

rollovers demo showing the changes to the HTML with classes added and removed

That way you can trigger drop shadows on the irregular shape only when the cursor is on any of the visible parts. It would be great if we had a way in CSS to do the same, but clipping and masking only have a visual outcome, they don’t limit the interaction area.

Other interesting articles:
CSS
JavaScript
See all articles