Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent repaint of other elements when using CSS transition

I am trying to prevent browser repainting to improve performance on a large single page app that makes use of CSS animations.

If I have an element that has a :hover { transform: scale(...) } effect on it, I can prevent repaints by using the will-change: transform and/or transform: translateZ(0) as mentioned here.

But as soon as I add a transition to that element, many elements start being repainted again.

Here is a demo codepen and a gif of itenter image description here

The only thing that worked to prevent this repaint is to put the other elements before the animating element in the DOM order, or to z-index the animating element above the other elements. But with a complex single-page app, I do not want to have to micromanage the z-index of any element that just wants a hover transition.

Any other ideas or references? I haven't seen this specific problem with transitions discussed elsewhere.

like image 664
Paul Kaplan Avatar asked Jan 21 '19 14:01

Paul Kaplan


People also ask

How do you stop a transition in CSS?

To pause an element's transition, use getComputedStyle and getPropertyValue at the point in the transition you want to pause it. Then set those CSS properties of that element equal to those values you just got.

Why would you use a CSS animation instead of a transition What are the differences between the two?

CSS transitions are generally best for simple from-to movements, while CSS animations are for more complex series of movements. It's easy to confuse CSS transitions and animations because they let you do similar things.

What is the difference between animation and transition in CSS?

Transitions animate a object from one point to another. Animation allows you to define Keyframes which varies from one state to another with various properties and time frame. Use transition for manipulating the value using JavaScript. Flexibility is provided by having multiple keyframes and easy loop.


1 Answers

It seemed like the position: absolute; on .other was not creating a new layer, I was able to solve the issue by adding transform: translateZ(0) to the .other class.

JSbin

Given that you're working on a SPA, i'm not sure how feasible this approach is, since there could be hundreds of elements after the circle.

like image 73
San Jarral Avatar answered Sep 17 '22 13:09

San Jarral