Animate Elements with CSS Animations & JQuery
Today, I wanted to feature a technique I have been using which quickly allows me to animate elements on a page with CSS animations. It will loop through each element on the page based on a CSS class and intermittently add an animation to that element. The method has fall-backs for browsers that do not support CSS animations (in that they just show on page load, but do not animate) so you never have to worry about the content not showing on older browsers. This method also prevents “glitchy” content blips that tend to occur with JQuery class additions on the document loading.
First, we must start with our HTML content:
<p class="animate">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean venenatis lacus sed urna lacinia varius. Nam in tellus et quam consectetur varius.</p> <p class="animate">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean venenatis lacus sed urna lacinia varius. Nam in tellus et quam consectetur varius.</p> <p class="animate">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean venenatis lacus sed urna lacinia varius. Nam in tellus et quam consectetur varius.</p> <p class="animate">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean venenatis lacus sed urna lacinia varius. Nam in tellus et quam consectetur varius.</p>
It contains 4 paragraphs, all with some Lorem Ipsum. What’s important is that each element is given a class of “animate”, which we will use as our selector. The class can be given to any element you were hoping to use a CSS animation for, which opens up the ability to constantly add/remove and dynamically pull elements without ever having to worry about the front-end animation suffering.
This is because of the JQuery you will see below:
$('.animate').each(function(i) { $(this).dequeue().delay(500*i).queue(function(){ $(this).addClass('animation'); }); });
Fire this JQuery snippet when your document is ready. Let’s talk a bit about what is happening here —
First, we use the each() selector to grab each element on the page with the “animate” class. Then, we are saying: “Every 500 milliseconds, add the class ‘animation’ to that element, wait 500 milliseconds, go onto the next element, add the class to that one, and so on, and so forth.” This function will go through every element with that class, add the animation class, and do this until they are all done.
I like this method because it delays the animation on each element by 500 milliseconds (which you of course can change the timing of), making a nice presentation no matter how many elements you have on the page.
You can, however, choose to simply queue all of the animations at once with this code instead:
$('.animate').addClass('animation');
Now that we have these core parts set up, the possibilities become endless with CSS. I wanted to ensure a fallback in case the CSS animations aren’t supported as well, so we will incorporate the new @supports rule.
@supports (-webkit-animation:test) or (animation:test) { .animate { opacity:0.0; } .animation { -webkit-animation:slideIn 1s forwards; animation:slideIn 1s forwards; } @-webkit-keyframes slideIn { from { opacity:0.0; -webkit-transform: translate(0px,40px); } to { opacity:1.0; -webkit-transform: translate(0,0); } } @-keyframes slideIn { from { opacity:0.0; transform: translate(0px,40px); } to { opacity:1.0; transform: translate(0,0); } } }
I am only relying on the -webkit- vendor prefix and full support, but you could open this up to more browsers by incorporating other vendor prefixes. I find that this works for a majority of my cases (and will only improve), so it is enough for me. The best part of this approach is that, worst case scenario, elements are given a class with our JQuery function and nothing happens on the front end. No content is hidden or lost.
Again, let’s beak this down —
First, we are using the rule declaration and nested a few CSS rules. If animations are supported, then I want to set the initial state of those elements. In this case, I am going to fade in these elements, so any element with the animate class is going to need to be hidden:
.animate { opacity:0.0; }
Next, I want to determine what we do when they are animated. The class “animation” is being added to each element, so let’s determine what that is:
.animation { -webkit-animation:slideIn 1s forwards; animation:slideIn 1s forwards; } @-webkit-keyframes slideIn { from { opacity:0.0; -webkit-transform: translate(0px,40px); } to { opacity:1.0; -webkit-transform: translate(0,0); } } @-keyframes slideIn { from { opacity:0.0; transform: translate(0px,40px); } to { opacity:1.0; transform: translate(0,0); } }
In this case, the keyframes of the animation are being determined by the “slideIn” animation. It transforms and fades the element in. In the CSS class, we are able to determine which animation is used, how long it takes, and the state it is in when the animation is done.
You can change any of these elements and that’s the biggest reason I favor this method over any other. I can update the CSS constantly, change animations, change how long they animate for, what they do, without ever modifying some of the main core code of HTML and JQuery.
If I ever want to animate another element, I can simply add the “animate” class to it and it will follow the same behavior. This allows for a robust amount of flexibility.
For example, I can adjust the animation for any element by giving it a new CSS rule without ever touching the HTML or JQuery code.
Say I want to have the first paragraph perpetually loop through its animation. I can do this with one simple new CSS rule:
p:first-of-type.animation { -webkit-animation:slideIn 2s 1s infinite; animation:slideIn 2s 1s infinite; }
And now, the first paragraph will run through the animation after 1 second of delay, run for 2 seconds, and loop infinitely.
You can make countless rules and animations for all of the elements on the page, and also determine their state before the animation occurs.
I hope this helps with your front-end development processes going forward. Feel free to explore this approach. Hopefully, its ability to scale will really make it a routine method in your process.