So, let’s smash some myths, dive into some real-world animation examples and improve our design skills in the process. If you love designing practical UI animations for your projects, this article is for you.
CSS animations are convenient when you need to sprinkle property transitions into your style sheets. Plus, they deliver fantastic performance out of the box — without your having to add libraries to the page. However, when you use CSS transitions to power rich motion design (the kind you see in the latest versions of iOS and Android), they become too difficult to manage or their features simply fall short.
- cross-browser SVG support,
- physics-based loader animations,
- timeline control,
- Bezier translations.
Velocity and GSAP
If jQuery is present on your page, you can use Velocity and GSAP just like you would jQuery’s
$.animate(). For example,
$element.animate( opacity: 0.5 ); simply becomes
$element.velocity( opacity: 0.5 ).
These two libraries also work when jQuery is not present on the page. This means that instead of chaining an animation call onto a jQuery element object — as just shown — you would pass the target element(s) to the animation call:
/* Working without jQuery */
Velocity(element, opacity: 0.5 , 1000); // Velocity
TweenMax.to(element, 1, opacity: 0.5 ); // GSAP
As shown, Velocity retains the same syntax as jQuery’s
$.animate(), even when it’s used without jQuery; just shift all arguments rightward by one position to make room for passing in the targeted elements in the first position.
GSAP, in contrast, uses an object-oriented API design, as well as convenient static methods. So, you can get full control over animations.
In both cases, you’re no longer animating a jQuery element object, but rather a raw DOM node. As a reminder, you access raw DOM nodes by using
document.querySelectorAll (which works similarly to jQuery’s selector engine). We’ll briefly work with these functions in the next section.
Working Without jQuery
(Note: If you need a basic primer on working with jQuery’s
$.animate(), refer to the first few panes in Velocity’s documentation.)
querySelectorAll further because it will likely be your weapon of choice when selecting elements without jQuery:
document.querySelectorAll("body"); // Get the body element
document.querySelectorAll(".squares"); // Get all elements with the "square" class
document.querySelectorAll("div"); // Get all divs
document.querySelectorAll("#main"); // Get the element with an id of "main"
document.querySelectorAll("#main div"); // Get the divs contained by "main"
As shown, you simply pass
querySelectorAll a CSS selector (the same selectors you would use in your style sheets), and it will return all matched elements in an array. Hence, you can do this:
/* Get all div elements. */
var divs = document.querySelectorAll("div");
/* Animate all divs at once. */
Velocity(divs, opacity: 0.5 , 1000); // Velocity
TweenMax.to(divs, 1, opacity: 0.5 ); // GSAP
Because we’re no longer attaching animations to jQuery element objects, you may be wondering how we can chain animations back to back, like this:
$element // jQuery element object
.velocity( opacity: 0.5 , 1000)
.velocity( opacity: 1 , 1000);
In Velocity, you simply call animations one after another:
/* These animations automatically chain onto one another. */
Velocity(element, opacity: 0.5 , 1000);
Velocity(element, opacity: 1 , 1000);
Animating this way has no performance drawback (as long as you cache the element being animated to a variable, instead of repeatedly doing
querySelectorAll lookups for the same element).
(Tip: With Velocity’s UI pack, you can create your own multi-call animations and give them custom names that you can later reference as Velocity’s first argument. See Velocity’s UI Pack documentation for more information.)
This one-Velocity-call-at-a-time process has a huge benefit: If you’re using promises with your Velocity animations, then each Velocity call will return an actionable promise object. You can learn more about working with promises in Jake Archibald’s article. They’re incredibly powerful.
In the case of GSAP, its expressive object-oriented API allows you to place your animations in a timeline, giving you control over scheduling and synchronization. You’re not limited to one-after-the-other chained animations; you can nest timelines, make animations overlap, etc:
var tl = new TimelineMax();
/* GSAP tweens chain by default, but you can specify exact insertion points in the timeline, including relative offsets. */
.to(element, 1, opacity: 0.5 )
.to(element, 1, opacity: 1 );
Animating Without jQuery