Dealing with CSS properties that are expensive to animate

Sujan Shrestha
3 min readApr 30, 2021

As many of you may have already known, we should not be randomly applying animation or transition to any of the property we like for the sake of performance because not all of them are cheap to render. This article is for those people that already know the dangerous outcome of animating such properties but have no idea how to deal with animations that don’t seem possible using the cheaper properties.

If you are not aware of what I’m talking about, take a moment to check this article by Paul Lewis.

Now, you know you should be applying animation and transition to properties that don’t trigger the paint and layout but composite. The most common properties to do this are opacity and transform. You can achieve almost any kind of animation using these two properties with the help of JavaScript in some cases. That’s good, but what if you want to animate things like borders, box shadows, background colors and so on?

This article covers some of the tricks you can use to trigger more performant animations on these properties.

Let’s suppose, you want to animate an element’s box shadow upon hover, you are most likely gonna apply the transition to the box-shadow property. That works, obviously… But this is going to affect performance and may feel a tad sluggish, especially on mobile devices. So the solution here would be the pseudo elements!

Pseudo elements like ::before and ::after can be handy in situations like this. In fact, the pseudo elements will be playing the main role behind helping us sort this problem out. Like I wrote above, the opacity property is cheap to animate and it triggers composite only so the trick would be to apply the box-shadow property to the pseudo element instead and set its opacity to 0, making it invisible by default. Then upon hovering the parent element, set the pseudo’s opacity to 1.

Check the CodePen example below to compare the two

The result is the same and the one using the pseudo element is much more performant on mobile devices because we are applying the transition to the opacity property here. You might say this method takes up more lines of codes but it’s worth it! I don’t think you should compromise user experience over few lines of codes.

Animating the border is relatively the same

There’s also one good thing here, the border set to the pseudo element doesn’t cause the parent to reflow like its own border does regardless of how thicker the border width is. It kind of acts like the inset value of the box-shadow property.

And to animate the background color, we are not really changing the background color of the element here, just stacking the pseudo element on top of its parent that has the color we need.

This one might look a bit funny as it’s a lot of work just to simply transition the background color but smooth experience is always better. Also, you can use this method for overlays and backdrops of certain elements with gradient background effect and so on.

That’s it. This article is to help those that don’t know the alternative ways to trigger performant animations on properties like these. Hope this helps some of you. Cheers! :)

--

--

Sujan Shrestha

I'm a self taught web developer, currently freelancing. I like to share things with others that I have learned.