I’m Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with , and . To receive more information, including news, updates, and tips, you should follow me on Twitter or add me on Google+.

web developer guide

my books

Book cover of Pro CSS3 AnimationPro CSS3 Animation, Apress, 2013

my other blogs

Massive Head Canon: Intelligent discussion of movies, books, games, and technology.

my projects

A Sass color keyword system for designers. Replaces CSS defaults with improved hues and more memorable, relevant color names.

CSSslidy: an auto-generated #RWD image slider. 3.8K of JS, no JQuery. Drop in images, add a line of CSS. Done.

tipster.ioAutomatically provides local tipping customs and percentages for services anywhere.

Dawn at Perhentian Island, Malaysia

“Curved” Dropshadows With Pure CSS

css / shadows

Estimated reading time: 2 minutes, 6 seconds

Previously I have demonstrated how to place curved dropshadows on HTML elements using a PNG shadow image generated with . Being forced to make the shadows with an application is a little irritating when we know that CSS has box-shadow. Surely there’s a way of creating curved shadows with just that property?

Right now, the answer is… “kinda”. As I’ll show you, we can get awfully close, especially if the effect you’re after is subtle, and we can add a few visual tricks… but at the moment the shadows can’t be bent into actual curves with just CSS. (That will have to wait for the advent of CSS shaders.)

I’ll use much the same method as the previous article. In that lesson, I used ::before and ::after pseudo-elements with their content properties set to an image. But there’s nothing that says that we must have any content defined in ::before or ::after … and those invisible pieces of content can still have their own shadows.

In this case I’ll wrap the image with a div, just to make things slightly easier:

<div class=shadowed>
<img src=perhentian-island-malaysia.jpg alt="Dawn at Perhentian Island" style=788px;height:526px>

Then, I apply much the same technique as before: this time, the div has position: relative, so our ::before and ::after effects will be positioned relative to it and not the body:

div#island-dawn { margin-bottom: 2rem; position: relative; }

We have to have some content for the pseudo-elements, but there’s no rule it has to be anything visible. In this case, I’ll make it a single space:

div#island-dawn:before,  div#island-dawn:after { content: " "; width: 80px; height: 8px; }

Then we’ll apply a box-shadow to these pseudo-elements, with a 15 pixel spread specified.

div#island-dawn:before,  div#island-dawn:after { content: " "; width: 80px; height: 8px;
box-shadow: rgba(0,0,0,0.6) 0px 0px 15px 8px; position: absolute; bottom: 7px; }

We’ll also push in the shadows from the left and right, and rotate each pseudo-element, after specifying where the element is rotated from. (The top left and right corners of the left and right shadows, respectively). Here, I’ll show the transforms sans vendor prefixes:

div#island-dawn:before { left: 22px; transform-origin: 0 left; transform: rotate(-4deg);  }
div#island-dawn:after { right: 11px; transform-origin: 0 right; transform: rotate(4deg); }

While the shadows remain “straight”, the effect is close enough to fool the eye of most casual observers. Possible enhancements include the possibility of rotating the shadows in depth with .

Photograph used with the kind permission of Choh Wah Ye, licensed under Creative Commons.

comments powered by Disqus

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.