Jerky CSS Animation? FLIP it!

  • 2
  • Article
  • Updated 3 years ago
You can create some great effects by using CSS animation to move elements in your templates. For example, you can use animations to create some cool, subtle animations for interactive displays to provide feedback to the user; like when the user selects a button it morphs to an X. You can also use animations to create background effects; moving larger elements across the screen, or creating a ‘Ken Burns’ style effect on a background image.

One method to move elements with CSS is to apply keyframe animations to an element which has position:absolute. Absolutely positioning elements allows them to be moved via positioning values top, bottom, left and right.

For example, a keyframe animation that would move an element 200px to the right and then back to it’s original position would look typically like this:

Screen Shot 2016-04-06 at 120807 PMpng

However, we have found that on some screens and at some resolutions, moving elements in this way can result in either a jerky motion or the edges of the element become jagged while it moves across the screen. This is especially noticeable when larger elements are moved at a slow speed over a large distance.

There are a few methods to improve the performance of CSS animations, and we are going to take a look at two in particular - using translate3d and the FLIP method. We have set up an example presentation here to show the different methods of moving elements on screen, and the full code is available here.

Using transform:translate3d()

This method improves the performance of the animation by getting an extra boost from the computer’s Graphics Processing Unit (GPU). Normally, CSS animations performed by the browser’s software rendering engine, which is slower. So how can we get access to this extra power?

Screen Shot 2016-04-06 at 122931 PMpng

Chrome will make use of the GPU when it is told that an element would benefit from it, and one way to do this is to apply a 3D transform. Any method which uses ...3d() will cause this to happen, such as translate3d() or scale3d(). The translate3d() method takes 3 different parameters, relating to x, y and z axis. So, to recreate the value of ‘right:200px’ in our example above, we would use transform:translate3d(200px,0,0). Note that you do not need to assign a value to the parameter for the z axis to trigger the extra power from the GPU, this will still work when moving the element in 2 dimensions.

We can now use this method to rework the keyframes example above:


Screen Shot 2016-04-06 at 120904 PMpng

The downside to this method is that it does use up more memory, so we suggest using them only on elements that need to be animated, and only when you notice a significant increase in the performance of the animation.

The FLIP technique

Another way to increase the performance of your CSS animations is to use the FLIP technique. FLIP stands for First, Last, Invert, Play, and describes the way that the keyframes are set up. You can read more about the method Paul Walsh’s FLIP library github page here but the basics are that you take snapshots of the element in the first and last positions, apply a transform to invert the changes, and then play the animation forward by removing the transformation applied in the invert step.
It sounds pretty complicated, so let’s look at how we would set up the same example as before:

Screen Shot 2016-04-06 at 122217 PMpng


This is particularly useful when animating effects following user interaction, like moving an element after a button is touched. The animation appears to be triggered faster as you have already told the browser where the animation will start and finish. Rather than writing out your own keyframes, you can take advantage of this awesome free library from Anna Migas here, as well as reading more about this method. 

You could also combine the FLIP technique with the transform:translate3d() method:

Screen Shot 2016-04-06 at 122628 PMpng


Anything else?
There are a couple of other CSS declarations that can be used to improve the look of animations and remove the ‘flicker’ that sometimes shows up at the edges of elements or text. Adding in the values backface:visibility-hidden, and perspective:1000 to the element styles, can help to maintain the crisp edges of the element or text while it is transitioned.

On older versions of Chrome, you may need to add the ‘-webkit-’ prefix to the keyframes and transitions for them to work correctly.

We hope you find these ideas useful, and have fun experimenting with animations in your own creations. Thanks!
Photo of Peter Cameron

Peter Cameron, Employee

  • 1,418 Points 1k badge 2x thumb

Posted 3 years ago

  • 2

There are no replies.