Dawn at Perhentian Island, Malaysia

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">
</div>

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 CSS3 3D.

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