Expanding CSS Shadow Effects â Frontend Masters Blog
Expanding CSS Shadow Effects â Frontend Masters Blog êŽë š
Design principles tell us a shadow is conveys that light is hiding an object, which casts the shadow behind it, giving us a sense of depth. However, if thatâs all a shadow is ever used for, then it has not been utilized to its full potential.
The Power of Shadows
Shadows in CSS can be multi-directional, layered, and are animate-able. On top of being all that, they donât affect the layout and computed size of an element even though they can make it appear bigger or smaller, which makes them an efficient tool for making visual changes.
Types of Shadows
There are different types of shadows based on the type of component they affect.
box-shadow
filter: drop-shadow()
text-shadow
The difference between box-shadow and drop-shadow() is worth knowing!
All of this is proof that youâll benefit from understanding CSS shadows and learning ways to expand their uses beyond simply creating a proverbial shadow.
Focus on Inset Box Shadows
In this article, for the purpose of simplicity, my examples will focus on box shadows, specifically, inset box shadows. However, the principles weâll be working with are same for all types of CSS shadows.
Below is an example of what could be possible with the things Iâll be covering in this article. Iâll show you more examples and design variants as we proceed further.
```html.pokemon {
box-shadow: 0 0 10px #eee,
inset 3px 3px 10px white,
inset -160px -160px 0 royalblue,
inset 160px -160px 0 green,
inset -160px 160px 0 blue,
inset 160px 160px 0 yellow;
/* etc. */
&:hover {
box-shadow: none;
transition: box-shadow linear 0.6s;
.text {
opacity: 0;
}
}
}
The above shows off the inset
keyword that box-shadow
can use in a couple of different ways. Inward shadows make for terrific overlays, since itâs painted on top of an elementâs background and originates from the edges of the elementâs padding box. The other thing we got to confirm is that the box-shadow
is indeed animate-able.
Changing the Shadowâs Shape
CSS shadows, by default, follow the shape of the component they are applied to â a box, text, or the opaque area of an element, depending on which shadow is used. By playing around with the shadowsâ vertical and horizontal offsets, you can reshape them to a degree. Hereâs an example:
.selected {
/* etc. */
box-shadow:
inset -30px 30px 0 white,
inset 30px -30px 0 white,
inset 0 0 80px lime;
transform: rotatez(360deg);
transition: transform 1s linear;
}
The element weâll apply this to is already a circle, and this will make the shadow somewhat football (đ) shaped.
In similar ways you can play around with a shadowâs blur radius, spread distance (in box-shadow
), and color.
Tips
Add a thin border matching the pageâs background to the element if thereâs any inset shadow bleeding outside the box
Animating Only Parts of a Shadow
We can take this a step further. So far weâve been animating the box-shadow
property as a whole, but how about pin-pointing the animation to individual values of a shadow? That will not only produce a different result, but you can also assign different animation times for different aspects of a shadow:
@property --l {
syntax: "<length>";
inherits: false;
initial-value: 0px;
}
@property --c {
syntax: "<color>";
inherits: false;
initial-value: red;
}
.selected {
/* etc. */
--l: 160px;
--c: black;
box-shadow: inset 0 0 0 var(--l) var(--c);
transition: --l 1s linear, --c 0.5s linear;
}
You can also use @keyframes
, instead of transition
, for the animations to keep frame stops. For instance, in the following example, thereâs multiple color changes throughout the animation sequence as defined by the @keyframes
ruleset, colorChange
:
@property --c {
syntax: "<color>";
inherits: false;
initial-value: dodgerblue;
}
@keyframes colorChange {
40% { --c: yellow }
80% { --c: red }
}
.selected {
/* etc. */
box-shadow: inset 0 0 0 var(--l) var(--c);
animation: 1s linear colorChange;
}
For our main demo, letâs keep transition
, and then combine the things weâve seen so far as well as include a few more colors.
@property --l {
syntax: "<length>";
inherits: false;
initial-value: 0px;
}
.selected {
/* etc. */
--l: 100px;
box-shadow:
inset var(--l) calc(-1 * var(--l)) 60px azure,
inset calc(-1 * var(--l)) var(--l) 60px white,
inset calc(-1 * var(--l)) calc(-1 * var(--l)) 60px white,
inset var(--l) var(--l) 60px white,
inset calc(-1 * var(--l)) calc(-1 * var(--l)) 5px fuchsia,
inset var(--l) var(--l) 5px lime, inset var(--l) calc(-1 * var(--l)) 5px red,
inset calc(-1 * var(--l)) var(--l) 5px green;
transition: --l 1s linear;
}
.selected {
/* etc. */
box-shadow:
inset 0 0 10px 30px white,
inset -40px 0px 0 white,
inset 40px 0px 0 white,
inset 0 0 100px red,
inset 0 -60px 0 white,
inset 60px 30px 0 white,
inset 0 0 100px blue;
transform: rotatez(360deg);
transition: box-shadow 1s linear, transform 1s linear;
}
This is where you can really see how layering can be helpful.
Other Examples
Hereâs a collection of a few on-hover animation designs using CSS shadows to help you get started:
If you want to keep exploring shadow animations further, I recommend combining them with other possible visual effects from CSS properties like filter and blend modes. Also, make sure to see how the animations work out both when individual values are animated and when the shadow as a whole property is animated.
Further Reference
- âA Few Interesting Ways To Use CSS Shadows For More Than Depthâ by me on Smashing Magazine
