Smoother & sharper shadows with layered box-shadows
As light hits an object and a shadow is cast, the shadow can take on a myriad of unique characteristics. If you try to capture the subtleties of a real shadow with box-shadow
then, well, you’re pretty much out of luck. The box-shadow
CSS property isn’t exactly built to encourage expressiveness. It essentially produces a blurred silhouette of an object—you can change its offset, blur radius, spread, and color, but that’s it. We can’t get anywhere near to expressing the complexities and nuances of shadows in real life.
But with a simple CSS technique, we can expand our range of options. If we use layered box-shadow
s we can get more fine-grained control over how shadows are rendered:
Look at how square and clumsy the default box-shadow
effect (first box) looks compared to the layered box-shadow
(second box). We can achieve this effect by creating multiple box-shadows
(separating each shadow with a comma), and increasing the offset and blur for every shadow (the box-shadow
syntax is X-offset Y-offset blur color
):
/* Default box-shadow */
.box {
box-shadow: 0 3px 3px rgba(0,0,0,0.2);
}
/* Create smoother box-shadows by layering multiple
* shadows with gradually increasing radius and offset */
.shadow-5 {
box-shadow: 0 1px 1px rgba(0,0,0,0.12),
0 2px 2px rgba(0,0,0,0.12),
0 4px 4px rgba(0,0,0,0.12),
0 8px 8px rgba(0,0,0,0.12),
0 16px 16px rgba(0,0,0,0.12);
}
This simple layering technique gives us more control over the rendering of shadows, and with it we can fine-tune sharpness, distance, and spread. You can for example increase or decrease the number of shadows to create a smaller or larger spread. (Note that if you increase the number of layers you’ll have to decrease the alpha value for each layer if you wish to keep the strength somewhat the same.)
.shadow-4 {
box-shadow: 0 1px 1px rgba(0,0,0,0.15),
0 2px 2px rgba(0,0,0,0.15),
0 4px 4px rgba(0,0,0,0.15),
0 8px 8px rgba(0,0,0,0.15);
}
.shadow-6 {
box-shadow: 0 1px 1px rgba(0,0,0,0.11),
0 2px 2px rgba(0,0,0,0.11),
0 4px 4px rgba(0,0,0,0.11),
0 8px 8px rgba(0,0,0,0.11),
0 16px 16px rgba(0,0,0,0.11),
0 32px 32px rgba(0,0,0,0.11);
}
Controlling sharpness is as easy as controlling spread, but we can use both the alpha value and the blur value of each layer to change the concentration of depth and the blur radius of the shadow respectively.
The examples above use the same alpha value for all layers, but we can let the alpha value decrease or increase with every layer to create more or less diffuse shadows. For the more concentrated shadow below, the innermost shadow (with the least offset and blur) has the highest alpha value, and it decreases with every layer. The opposite is true for the more diffuse shadow of the second box, where the innermost layer has the lowest alpha value:
.blog-shadow-sharp {
box-shadow: 0 1px 1px rgba(0,0,0,0.25),
0 2px 2px rgba(0,0,0,0.20),
0 4px 4px rgba(0,0,0,0.15),
0 8px 8px rgba(0,0,0,0.10),
0 16px 16px rgba(0,0,0,0.05);
}
.blog-shadow-diffuse {
box-shadow: 0 1px 1px rgba(0,0,0,0.08),
0 2px 2px rgba(0,0,0,0.12),
0 4px 4px rgba(0,0,0,0.16),
0 8px 8px rgba(0,0,0,0.20);
}
We can also increase the blur
in higher incremenents, to increase the spread and create softer, almost dreamy, effects:
.blog-shadow-dreamy {
box-shadow: 0 1px 2px rgba(0,0,0,0.07),
0 2px 4px rgba(0,0,0,0.07),
0 4px 8px rgba(0,0,0,0.07),
0 8px 16px rgba(0,0,0,0.07),
0 16px 32px rgba(0,0,0,0.07),
0 32px 64px rgba(0,0,0,0.07);
}
Finally, we can control the distance by decoupling the blur radius and Y-offset, and increase the offset in bigger or smaller increments:
.shadow-shorter {
box-shadow: 0 1px 1px rgba(0,0,0,0.11),
0 2px 2px rgba(0,0,0,0.11),
0 4px 4px rgba(0,0,0,0.11),
0 6px 8px rgba(0,0,0,0.11),
0 8px 16px rgba(0,0,0,0.11);
}
.shadow-longer {
box-shadow: 0 2px 1px rgba(0,0,0,0.09),
0 4px 2px rgba(0,0,0,0.09),
0 8px 4px rgba(0,0,0,0.09),
0 16px 8px rgba(0,0,0,0.09),
0 32px 16px rgba(0,0,0,0.09);
}
Which combination of all of these techniques to use is of course highly dependent on the context that you’re working in, but with layered shadows we can at the very least gain some more control to help us achieve our desired look and feel.