Custom Animations With CSS & Javascript

Matthew Steele
Oct 15, 2020 · 4 min read

Make your application move from scratch — no libraries, no plug-ins.

During Mod 3 at Flatiron School in Chicago, we were tasked with creating our second application combining several frontend and backend technologies including Javascript, HTML, CSS, and Ruby on Rails. My team and I opted to build a classic card-matching game with a fun, educational twist (see below for a full demo of our application).

In conceptualizing and designing our game, we wanted to create something stunning — colorful, yet minimal with seamless animations rooted in user interaction.

Prior to building this game, I had only used CSS for styling and briefly touched animations with hover — Rails Front-End with HTML/CSS. Therefore, each piece of this game was a learning process and an ultimate discovery. Hopefully, this blog summarizes that journey for other aspiring engineers.

Note: While in Mod3 at Flatiron, we only briefly covered HTML/CSS and had not yet implemented a Javascript framework like React. There may be better ways to implement animations especially while using a framework. However, before React, this blog covers the best solutions I found to bring life to our game.

Animations:

User loads new card game triggering multiple animations.

CSS Configuration ↓

There are four animations occurring in the example above — each card row enters the page with unique animations and our leaf notification enters and exits with two separate animations.

While demonstrating configuration, we will focus on the leaf notification’s exit animation. All four animations are configured and set up in the same way, each with unique keyframe properties.

@keyframes leaf-exit {
0% {
transform: translateY(0) rotateX(0) scale(1);
transform-origin: 50% 1400px;
opacity: 1;
}
100% {
transform: translateY(-600px) rotateX(-30deg) scale(0);
transform-origin: 50% 100%;
opacity: 1;
}
}

1. Animation Properties

The first step in creating your custom CSS animations is declaring your keyframes (structure above) with a name property, like leaf-exit. The name will come in handy when we need to transition from one animation to another using Javascript. Similarly, there are many other animation properties, like animation-duration, that we will apply using Javascript.

2. Keyframe Selectors

Compare an animation to a short video created in your application — 0%{} is the first frame of your video declared by your first keyframe, while 100%{} is the last. When you initialize your animation, keyframes (one or many) dictate changes to your element at the designated frames.

3. Keyframe Properties

Inside our selected keyframes, we use multiple properties to change the position and appearance of an element like transform (with sub-properties), transform-origin, and opacity. Learning and understanding animation properties and sub-properties to modify frames is a time-consuming journey in itself, mostly experimental. However, there are free simulators (resources) that will automatically generate these properties, saving us the confusion and time.

Javascript Sequence ↓

In our application, user interaction triggers the start of the demonstrated animations via a listener attached to a button. Subsequently, a new game loads and initializes follow-up animations by calling toggleCardsUp().

function renderNotification() {
leaf.style.display = 'block'
leaf.style.animationName = 'leaf-enter'
leaf.style.animationDuration = '.4s'
setTimeout(floatNotification, 400)
}
function floatNotification() {
leaf.style.animationName = 'leaf-exit'
leaf.style.animationDuration = '.7s'
setTimeout(hideNotification, 700)
}
function hideNotification() {
leaf.style.display = 'none'
}

1. Initialize

In some cases, you may want your animation to run automatically. However, in the case of user interaction triggered animations, we will update an element’s animation properties inside of a Javascript function.

For example, before a user starts a new game, our leaf notification’s display equals ‘none’ , and we have yet to assign an animation property in our CSS stylesheet. When a user starts a new game and triggers toggleCardsUp(), our primary renderNotification() function is also triggered.

Initialization is the most important part of this process. We use this function to update several properties of our leaf notification. First, we set display equal to ‘block’. In some cases, you can clear or reset the display by using an empty string ‘’.

Then, we assign an animation name and duration, which ‘plays’ a previously configured animation unless you have an animation-play-state property set to ‘paused’.

2. Transition

If we are ‘playing’ multiple animations back-to-back, we can transition using Javascript’s built-in timing event, setTimeout(function, milliseconds). In our example, leaf notification renders, then leaf-enter completes after .4s duration. We set a timeout for 400 milliseconds and trigger a second function the exact moment the first animation finishes. floatNotification() will update our animation properties again and ‘play’ our second animation, leaf-exit. Voila — transition!

3. Deactivate

In some scenarios, you may have a default animation assigned to an element and can play or pause the animation with Javascript by calling elementName.style.animationPlayState = ‘play/pause’ inside of a function.

For our leaf notification, our second animation has a duration and doesn’t continuously play. Therefore, instead of ‘pausing’ the animation, we simply need to update the leaf’s display so that it ‘disappears’ when the second animation is complete. We set another timeout for the exact length (in milliseconds) of our second animation’s duration. This will call our last function hideNotification() when leaf-exit finishes and ultimately updates our leaf’s display to ‘none’.

Recycle & Re-Use

Congratulations! You just configured and implemented an animation with CSS & Javascript. Now what? The great thing about writing animation code is that you can utilize it many times throughout any feature or page of your application! Our leaf notification renders each time a user loads a game, shuffles their cards, matches a pair of cards, or wins a game — all with one line of code — renderNotification().

Full Application Demo ↓

Resources

The Startup

Get smarter at building your thing. Join The Startup’s +731K followers.