How to animate Box – Shadow with Silky smooth Performance
This article is not a literal translation, because I think this technique is very interesting and useful, so I started the article.
Box-shadow is used more and more in our work, and the animation that accompanies shadow is more or less a little bit. Suppose we have the following box:
div {
width: 100px;
height: 100px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}
Copy the code
To hover, the box shadow moves from box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3) to box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3).
Box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3)
–>Box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3)
OK, the easiest way is of course:
div:hover {
width: 100px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
Copy the code
Since the transition animation takes place in two different box shadows, the browser will constantly redraw the box shadows during the transition animation. And because shadows are a consumption style, the animation feels somewhat sluggish.
Here is a tip to optimize shadow animation in this case.
Optimize with pseudo-elements and transparency
To optimize with pseudo-elements and transparency, we add a before pseudo-element with the same size as the parent div, and give the element the desired final box shadow state in advance, but the transparency of the element is 0.
div {
position: relative;
width: 100px;
height: 100px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}
div::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
opacity: 0;
}
Copy the code
Then, with hover, we simply set the transparency of the pseudo-element from 0 to 1.
div:hover::before {
opacity: 1;
}
Copy the code
The nice thing about this is that the actual shadow changes that are going on are just the opacity changes, rather than the constant repainting of the shadow, which effectively improves the smoothness of the shadow animation and makes it look silky.
Why is animating opacity better than box-shadow? Take a look at this table, which lists the effects of different attribute changes on page rearrangement and redrawing:
very few CSS properties
Finally, the Demo can look at:
CodePen Demo — Optimized box-shadow animation
There are problems with another scheme
The above scheme in the original text is not perfect, because the final effect is a superposition of two shadows, which may make the overall feeling of the shadow a little darker.
So we need to tweak the final state of the shadow, weaken the effect a little bit, try to make two shadow overlay effect is similar to a single shadow effect.
Of course, we can optimize the scheme again by using ::after pseudo-element, ::after pseudo-element set to initial state and transparency 1, ::before pseudo-element set to last state and transparency 0:
div {
position: relative;
width: 100px;
height: 100px;
}
div::before {
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
opacity: 0;
}
div::after {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}
Copy the code
When actually hover, perform one show and one hide on two pseudo-elements, so that the final effect is only one shadow effect, no shadow overlay, which is the same as the effect of direct shadow transition change:
div:hover::before {
opacity: 1;
}
div:hover::after {
opacity: 0;
}
Copy the code
CodePen Demo — Optimized box-shadow animation
The last
Well, the end of this article, I hope to help you 🙂
More interesting CSS technology articles are summarized in my Github — iCSS, constantly updated, welcome to click on the star subscription favorites.