Web Animation

the CSS way

Amanda Holl
Kantata Product Development
7 min readFeb 6, 2018

--

illustration by Rob Levin

Before I dive into how to get started with CSS animations, I first want to ask, why bother?

Animation is complicated and time-consuming, so why take the time and effort to develop animated content for your websites and web apps?

First, animation can provide important feedback about how your application works and build confidence that it works correctly. Let’s take the example of a submit button. A user fills out a form on your site, and then hits ‘Submit’. Imagine that the page does not change at all when the button is clicked. Suddenly the user is confused, thinking that his or her information was not submitted or that the page is frozen, even if the submit worked correctly. This is a poor user experience that undermines the user’s confidence in your product. Contrast this with a submit button that, when clicked, displays an animated loader that visually shows the user that his or her information is being processed. This is a much better user experience that gives users confidence in your product, making the time spent animating worth the effort.

Animation also more effectively captures users’ attention and is more engaging than static content. This encourages users to spend more time on your page and click through content, making animation a huge marketing advantage.

For content heavy sites and applications, animation can also be an effective way of presenting dense concepts in a way that is easier to understand and reason about.

So now that I’ve hopefully convinced you that animation can be worth your time and energy, let’s talk about how to animate for the web.

You have a few different options for web animations. These include CSS animations, which are accomplished using CSS keyframes and animation properties, jQuery, done using the .animate() method, and JavaScript libraries like D3, WebGL, and GSAP.

Depending on your use case, one of these approaches might make more sense than the other. If, for example, you wanted to build interactive 3D shapes for mathematical visualizations, I would probably recommend you go with WebGL for its advanced 3D rendering capabilities, whereas I might recommend jQuery if you are animating a scroll to a different section of a page. I may cover jQuery and Javascript as follow up posts, but for now I will start with CSS since it is relatively simple to get started with and widely used.

CSS: the basics

CSS animations are created using keyframes and animation properties.

Keyframes, which define the styles of an animation, consist of an animation name, animation stages, and the CSS properties being animated. In the example below, the animation’s name is fadeIn. The animation has three stages, 0% being the first and 100% being the final stage. In the stages, the CSS properties that are animated are transform, opacity, and fill.

Animation properties apply a @keyframe to the element you want to animate and specify how the element’s style changes over time. To animate an element, simply add animation properties to it via the animation- set of CSS properties.

The animation properties are:

  1. Animation-name (required)
  2. Animation-duration (required)
  3. Animation-delay
  4. Animation-iteration-count
  5. Animation-direction
  6. Animation-timing-function
  7. Animation-fill-mode
  8. Animation-play-state

The animation properties can be declared individually for an element, or all at once using the shorthand syntax: animation: [animation-name] [animation-duration] [animation-timing-function] [animation-delay] [animation-iteration-count] [animation-direction] [animation-fill-mode];

Animation name

The first required animation property, animation name, binds a @keyframe to the element being animated.

Animation duration

The second required animation property, animation duration, specifies how long the animation should run, given as a value in seconds or milliseconds.

Animation delay function

Animation delay is a numeric value, given in either seconds or milliseconds, that defines when and where the animation starts. A positive value means that the animation begins after the given amount of seconds have elapsed. A negative value means that the animations begins immediately, but at the given amount of seconds into the animation. So an animation with a duration of 4s and an animation delay of -2s starts with 2 seconds of the animation left to play.

Animation iteration count

Animation iteration count specifies how many times the animation plays. This can be a numeric value for an animation that you want to play a fixed number of times or infinite for an animation that you want to play forever.

Animation direction

The animation direction property describes how the animation transitions from the first keyframe stage (0%) to the last keyframe stage (100%) in a given cycle of the animation. The values are:

  • normal (default) — The animation always starts at 0% and plays forwards to 100%
  • reverse — The animation always starts at 100% and plays backwards to 0%
  • alternate — The animation reverses direction each time it runs. On an odd cycle, the animation plays forwards from 0% to 100%. On an even cycle, the animation plays in reverse from 100% to 0%
  • alternate-reverse — The animation reverses direction each time it runs, but the first iteration plays in reverse. So, on an odd cycle, the animation plays backwards from 100% to 0%. On an even cycle, the animation plays forwards from 0% to 100%

Animation timing function

The animation timing function describes the pace at which the animation changes between states. Example values include:

  • linear — the animation plays at the same speed throughout its duration
  • ease-in — the animation starts slow and then speeds up over time
  • cubic-bezier() — the animation pace follows a cubic Bézier curve

The default value is ease, so the animation starts slow, speeds up over time, and then slows at the end. All of the timing options are provided here.

Animation fill mode

Animation fill mode determines whether the animation styles are present before and/or after the animation plays. The values are:

  • normal (default) — The animation styles do not affect the element before or after the animation finishes playing
  • backwards — Before the animation plays, the element has the styles defined in the first keyframe stage
  • forwards — After the animation plays, the elements keeps the styles defined in the last keyframe stage
  • both — The element has the styles defined in the first keyframe stage before the animation plays and keeps the styles defined in the last keyframe stage after the animation finishes playing

Animation play state

Animation play state defines whether the animation is playing or paused, which are the two valid values for this property. This gives your animation the ability to react to simple user interactions. In the example below, hover over a circle to pause its animation.

Now that we’ve gone over the basics of CSS animations, let’s talk about how useful they can be and their limitations.

CSS animations are relatively simple and easy to learn. They are also good for simple transitions between states and give you the ability to respond to simple user interaction like hover. With regards to performance, CSS animations are substantially faster than jQuery animations and are usually faster than Javascript because CSS uses browser-side transitions for animations. Additionally, your computer can accelerate many of the calculations done in transitioning between CSS animation states by using a GPU instead of CPU for processing. Read more about animation performance here.

CSS: the bad

CSS animations are a poor solution when you want to accomplish more advanced animations. Unless you also use Javascript or jQuery to dynamically add classes to elements, you cannot animate elements in response to complex user interactions, like click or swipe, which is often desired when you want your animations to be interactive and engage users as a means of revealing information. There is also a lack of independent scale, rotation, position manipulation within the phases of a keyframe because all of these properties are controlled by the single CSS property transform. Compatibility can also be an issue because CSS animations rely on CSS3 so they do not work in IE9 or earlier, which can be a constraint depending on the user base for your application or site.

Now you know how to create a CSS animation, but what about testing them?

I won’t get into details about how to test animations, but I will share some suggestions about when to test them and how to approach them. In general, when trying to test an animation, I like to ask myself two questions:

  1. Is a test necessary?
  2. How quickly is the animation happening?

Those of us who love to TDD our work or guard all of our code with many tests might be tempted to immediately start testing all of the animations we write. I would caution you to think about whether the animation drives a feature important to your users. We don’t test every line of our general CSS styles, so we probably don’t need to test every keyframe and animation if it doesn’t have user-facing value. If my animation changes the background color of a div to draw attention to the ad content in it, this is probably not a critical feature to users and therefore likely does not merit a test. If my animation, however, controls the opening and closing of a sub navigation panel, this animation should be tested because if my animation breaks, users would not be able to use my application as intended.

A second consideration for testing animations is how quickly the animations take place. If your animation has a very short duration, it’s possible that the web driver that drives your tests may not be able to detect a discernible change before and after your animation runs. In this case, any test you write will likely intermittently fail.

If you decide to write tests around your animation, it can be helpful to write shared helpers that can be used in multiple places to test the same behavior. This gives you reusability and a single place to fix any intermittent failure issues that may arise because of your animation test. You may also need to get creative about how you check that you animation ends up in the correct final state, such as by checking for the presence of CSS classes or text context in or outside of your animation. In general though, remember that animations are implemented by browsers, so you should be testing that animation is triggered correctly or has the correct final state according to other elements on the page.

Happy animating!

--

--