July 12, 2021
Incorporating elastic ease in CSS animations

As someone who’s created countless CSS animations, one thing I’ve always missed is elastic ease for keyframes and transition. Yes, you can use JavaScript libraries and other trickery (which we’ll get to in a moment), but, being the purest that I am, I’ve dove into the subject, checked out current solutions, learned the math behind it all, and built a CSS elastic ease generator that outputs a pure, clean, and accurate CSS animation code.

What is elastic ease in CSS?

First, let’s try to better understand the elastic ease motion of an object. Let’s look at a red ball moving from point A to point B:

The ball starts at point A, moving toward its destination to point B, but it overshoots point B by some margin, effectively moving away from it. Then, it starts to slow down, stops, and starts moving in the other direction, back toward point B. It once again overshoots point B — this time by less margin — and continues repeating this pattern while decreasing the margin each time until it finally stops.

Here’s what elastic ease movement looks like on a graph.

The ball’s starting point
Initial movement
Over-shooting the destination
Repeating the pattern
Endpoint

Using animation libraries in JavaScript

If you’re using an animation library like GreenSock, just add ease:Elastic.easeOut and keep on coding. It should be noted that while third-party solutions can help you overcome many hurdles, they do come with a price — sometimes literally — and they might affect your loading time, bundle size, and so on.

Coding for elastic ease in JavaScript

If you don’t want to (or can’t) use JS libraries, don’t worry, you can still implement an easing function with pure code. Yes, it requires more than one line of code, but it’s pretty simple, and I already did most of the work for you:

Elastic ease – #1: JS demo

No Description

What we have here is a simple elastic() function that takes in a value between 0 and 1 (the dotValue), and translates it to the correct X position (the elasticPosition) of the dot. The function also takes in two constants: speed, which affects the duration of the animation, and the velocity of the movement. Feel free to play around with these numbers to see how they affect the dot’s movement.

When we click Run, the dotValue resets to 0, and the function starts. It then runs constantly, using the requestAnimationFrame function, increasing the value by speed on each iteration and re-calculating the dot’s position for the new value. When the dotValue gets to 1, it stops.

As for the math, I must admit that my math skills are nowhere near good enough to properly explain what’s going on there, but I did check a few variations of this function from several different resources and ended up with this version, which is based on the math used by easings.net, plus some minor improvements.

In this example, I’ve used the setProperty function that sets a CSS custom property that controls the left position of the dot, but you can easily use it to control an element’s size, opacity, angle, color, and more. Just make sure that the input value is between 0 and 1, and that the two const are properly defined according to your needs.

Using CSS cubic-bezier ease for single-step elasticity

One simple yet fantastic solution is to use cubic-bezier ease to get a single-step elastic. You can do so by giving the fourth parameter of the function a high enough value so that the animation passes its destination, then return to its final value.

It’s not as rich as the other solutions, but it doesn’t use JS, it’s easy, and sometimes it’s all you need. I’ve created a few examples based on this method, and you can play around with cubic-bezier to get the exact result you want using this great tool by Lea Verou.

Elastic ease – #2: cubic-bezier

No Description

Using keyframes in CSS for elastic ease

Another way of achieving pure CSS elastic ease is to manually define each step of the movement with an animation keyframe to better understand this method. Let’s look at the movement on a graph one more time:

Here, you can see that the movement is divided into segments, which are separated by a vertical dashed line. Notice that the movement on each of these segments is just like the built-in CSS ease-in-out timing function that we all know, so we can translate each segment to a keyframe and get a fully elastic movement with pure CSS.

The problem with this method is that you first need to calculate each keyframe position and value, which is not an easy task. And, if you’re not accurate, the result might look jittery and inconsistent. To solve this, I’ve built a simple generator that creates the keyframes for you according to your parameters.

To allow for maximum versatility, we need to control three variables that, in turn, will control the trajectory of the movement:

Steps: the number of back-and-forth repetitions

Deceleration: to control the relation between each repetition

Velocity: sets the offset of the ease from the original path

Creating segment sizes for the animation

Let’s break this down. We’ll start with the number of steps (segments) the animation has and the deceleration between them. This is important because each step will be later translated into a keyframe, and the size of each step will determine the keyframe position.

Elastic ease – #3: Steps

No Description

If you move the Steps slider, you control the number of segments that the movement will be built from. The Deceleration bar sets the size relation. When the slider is all the way to the left, all the segments will be the same size. If the slider is positioned to the far right, each segment will be half the size of the previous one. Note that if you use too many steps with a high deceleration value, the last few steps may be too small to have any effect.

Setting velocity

Now that we have positions of the keyframes, let’s talk about the values. We’ll say that the initial value will always be 0, and the end value will always be 1. This way, we can later map these values to any CSS properties, and the velocity level will determine how much each step will deviate from the end value.

Elastic ease – #4: Velocity

No Description

Now that we have a nice elastic graph, the last step we have to complete is to add a duration slider that sets the overall time of the animation, then decide what we want to animate.

In this generator, I’ve added options to animate some commonly used properties, like width, height, and transform, but you can easily adjust it to animate pretty much any property you need.

Using the generator

CSS Elastic ease generator

No Description

Now, open the generator on a full screen. Use the generator’s inputs to control the movement as you please, copy the output code, and use it in your project to add elasticity to your animations.

You can edit and change the animation for your needs. For example, you can drop animation-fill-mode and add animation-iteration-count: infinite; if you want your animation to loop. Or, you can add animation-direction: alternate;, animation-delay, and even combine two animations for different properties.

Here’s a cool example of animations that are using keyframes created by this generator:

Elastic ease – #5: Examples

No Description

Conclusion

I dream that one day CSS will have a built-in elastic function and that this generator will become useless. Think how nice it would be to have a simple elastic function that accepts these three arguments and produces a clean and beautiful elastic ease, like so:

.elasticObject {
  animation-name: goElastic;
  animation-duration: 1.5s;
  animation-timing-function: elastic(7, 1.9, 0.5);
}

Until then, feel free to use this generator for anything you need, and if you have any thoughts or suggestions about how to improve this method, write them in the comments. Thanks!

The post Incorporating elastic ease in CSS animations appeared first on LogRocket Blog.

Leave a Reply

Your email address will not be published. Required fields are marked *

Send