This content originally appeared on Go Make Things and was authored by Go Make Things
For years, my go-to recommendation for CSS animations was animate.css by Daniel Eden.
It’s a great library, but it also a library. I generally only need one or two animations, and it includes way more stuff than I typically want in a project.
So I was delighted to discover Animista by Ana Travis last week. Animista is a tool that lets you select the animation you want, and then copy/paste the CSS for it into your project. That’s exactly the kind of workflow I want for stuff like this!
Today, let’s look at how to use it.
Some HTML
Let’s imagine I have a button.
<button>Click me, yo!</button>
When someone clicks it, I want the button to spin in a circle and grow bigger.
(Why? Who knows. Whimsy.)
Getting the animation CSS
On the Animsta website, I select the rotate-scale animation, and stick with the default rotate-scale-up option.
Then, I click the generate code button ({}
), and unselect the autoprefixer option. Then, I copy/paste the rotation class and keyframe into my project.
.rotate-scale-up {
animation: rotate-scale-up 0.65s linear both;
}
/* ----------------------------------------------
* Generated by Animista on 2021-5-17 9:55:12
* Licensed under FreeBSD License.
* See http://animista.net/license for more info.
* w: http://animista.net, t: @cssanimista
* ---------------------------------------------- */
/**
* ----------------------------------------
* animation rotate-scale-up
* ----------------------------------------
*/
@keyframes rotate-scale-up {
0% {
transform: scale(1) rotateZ(0);
}
50% {
transform: scale(2) rotateZ(180deg);
}
100% {
transform: scale(1) rotateZ(360deg);
}
}
Now I’m ready to animate my button.
Adding the animation to the button
First, I use the document.querySelector()
method to get my button
element. Then, I add an event listener for click
events on it.
// Get the button
let button = document.querySelector('button');
// Listen for clicks on the button
button.addEventListener('click', function () {
// Do something when the button is clicked...
});
When the button
is clicked, I can use the classList.add()
method to add my .rotate-scale-up
class to the button
. This makes it rotate.
button.addEventListener('click', function () {
button.classList.add('rotate-scale-up');
});
Pretty cool! Unfortunately, this only works once. Let’s figure out how to fix that.
Making the animation run more than once
When the .rotate-scale-up
class is added, the animation runs.
After the class is set on the element, the classList.add()
method doesn’t do anything because the class already exists. With no change to the element, the animation never runs again.
To fix this, we want to listen for when the animation ends on the button
, and remove the class when its done.
We can do that with the animationend
event. We’ll add our listener inside the click
event listener callback. We’ll also set the once
option to true
so that the event listener is removed after the animation.
button.addEventListener('click', function () {
button.classList.add('rotate-scale-up');
button.addEventListener('animationend', function () {
button.classList.remove('rotate-scale-up');
}, {once: true});
});
Now, the button animates every time its clicked. Here’s an updated demo.
Important accessibility concerns
Animations can make people who experience motion sickness, vertigo, and other conditions physically sick, dizzy, and disoriented.
Both Windows and macOS provide a way to disable animations at the operating system level, and tell websites that they would prefer not to see them as well.
We can access this setting through a CSS media query: prefers-reduced-motion
.
@media (prefers-reduced-motion: reduce) {
/* The user does not want animations */
}
@media (prefers-reduced-motion: no-preference) {
/* The user is OK with animations */
}
We can use this to turn on our animations only when the user wants them, or disable them when they don’t.
For a no animations first approach, we would wrap all of our CSS animation code in prefers-reduced-motion: no-preference
.rotate-scale-up {
animation: rotate-scale-up 0.65s linear both;
}
/* ----------------------------------------------
* Generated by Animista on 2021-5-17 9:41:40
* Licensed under FreeBSD License.
* See http://animista.net/license for more info.
* w: http://animista.net, t: @cssanimista
* ---------------------------------------------- */
/**
* ----------------------------------------
* animation rotate-scale-up
* ----------------------------------------
*/
@keyframes rotate-scale-up {
0% {
transform: scale(1) rotateZ(0);
}
50% {
transform: scale(2) rotateZ(180deg);
}
100% {
transform: scale(1) rotateZ(360deg);
}
}
Alternatively, we can remove all animations when they’re specifically disabled.
/**
* Remove all animations and transitions for people that prefer not to see them
*/
@media (prefers-reduced-motion: reduce) {
* {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
We use !important
here even though it’s generally frowned upon because we always want to remove animations when the user says they don’t want them.
This approach also reduces animations to a fraction of a millisecond (and thus imperceivable) rather than setting it to 0
so that any event handlers that hook into the animationend
event will still run.
Here’s a demo with proper accessibility considerations.
Abstracting adding an animation
What if you have multiple animations you want to add to your project? Let’s look at how we can abstract adding and removing our animation class.
First, let’s create an animate()
helper function. We’ll accept the node
to animate and the animation
as parameters.
function animate (node, animation) {
// Animate stuff...
}
Inside the animate()
function, we’ll add the animation
class to our node
, then setup the animationend
event listener and remove it.
function animate (node, animation) {
node.classList.add(animation);
node.addEventListener('animationend', function () {
node.classList.remove(animation);
}, {once: true});
}
Now, we can run our animation like this.
button.addEventListener('click', function () {
animate(button, 'rotate-scale-up');
});
If you wanted to trigger the animation in response to something else, you could run the animate()
function outside of a click
event.
animate(button, 'rotate-scale-up');
Here’s a demo with the abstracted code.
Adding a callback after the event
What if you wanted to do something else after the animation ends?
Let’s add one more parameter to our animate()
function: a callback function to run after the animation ends. We’ll pass in the node
and animation
as arguments.
function animate (node, animation, onEnd = function () {}) {
node.classList.add(animation);
node.addEventListener('animationend', function () {
node.classList.remove(animation);
onEnd(node, animation);
}, {once: true});
}
Now, you can do something like this.
animate(button, 'rotate-scale-up', function (node, animation) {
alert(`The ${animation} animation finished on an element.`);
});
You can find the animate()
helper function on the Vanilla JS Toolkit as well.
This content originally appeared on Go Make Things and was authored by Go Make Things
Go Make Things | Sciencx (2021-05-17T14:30:00+00:00) How to easily add CSS animations to your projects. Retrieved from https://www.scien.cx/2021/05/17/how-to-easily-add-css-animations-to-your-projects/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.