CSS Animation Effects

Part 2. CSS Animations

CSS Transitions are efficient enough to move HTML elements, rotate them, grow or shrink UI widgets and text. However, more elaborate effects can be created by turning to CSS3 Animations. An elementary example of a CSS keyframe style rule could look like this:

<style type="text/css">
 @keyframes demo {
  0% {background-color: red;}
  50% {background-color: green;}
  100% {background-color: blue;}
 }
</style>

In the code above the @keyframes is a keyword starting the keyframe rule. The keyword is still prefixed in Chrome, Opera and Safari (-webkit). The keyframe selector is denoted by comma-separated percentage values. Two keywords can be used instead of percentages: the keyword from is a substitute for 0%, and the keyword to is applied in place of 100%. Each keyframe declaration consists of the CSS background-color property and its corresponding value. The list of animatable properties is browser-specific. Here's another example, this time slightly modified: the code uses a list of both percentage values and keywords. In this case transition of colors will follow the RED (0%) GREEN (50%) RED (70%) BLUE(100%) pattern:

<style type="text/css">
 @keyframes demo {
  from {background-color: red;}
  50% {background-color: green;}
  70% {background-color: red;}
  to {background-color: blue;}
 }
</style>

The next step is to choose a target HTML element and specify parameters necessary to display the effect. The minimum requirement is to declare a name of the animation and predefine its duration:

<style type="text/css">
 #animatable {
  animation-name: demo; /* name of the keyframe rule */
  animation-duration: 4s; /* duration expressed in seconds */
 }
</style>

The animation-name property can have multiple values: for example, the code below alters the background color of an element and simultaneously changes its width.

<style type="text/css">
 @keyframes demo1 { /* keyframe rule 1 */
  0% {background-color: red;}
  50% {background-color: green;}
  100% {background-color: blue;}
}
 @keyframes demo2 { /* keyframe rule 2 */
  from {width: 100%;}
  to {width: 10%;}
 }
 #animatable {
  animation-name: demo1, demo2; /* both keyframe rules are applied */
  animation-duration: 12s;
 }
</style>

The animation-duration property defines the period of time required for an animation effect to complete a single cycle. Values are expressed in seconds or milliseconds. If an element uses more than one keyframe rules, animation-duration may accept a list of comma-separated values: in the example above the animation-duration: 12s; rule is equivalent to animation-duration: 12s, 12s;.

Additional CSS properties facilitates the creation of more advanced effects. First of all, the animation-delay property may state the point of time when the animation will start. Default value of the property is 0s: it means that animation will start immediately. Besides, it is often required to indicate the count of cycles for an animation effect. The animation-iteration-count property answers this purpose: it is a number, or it can have the infinite value. To invert the natural order of displaying an effect, the animation-direction property should be used. The list of standard values for the direction of frames include normal, reverse, alternate and alternate-reverse.

Here's an illustration of applying different values to the animation direction:

<style type="text/css">
 @keyframes demo1 { /* keyframe rule 1 */
  0% {background-color: red;}
  100% {background-color: blue;}
 }
 @keyframes demo2 { /* keyframe rule 2 */
  from {width: 100%;}
  to {width:10%;}
}
 #animatable {
  animation-name: demo1, demo2; /* both keyframe rules are applied */
  animation-delay: 0s;
  animation-direction: normal; /* default value */
  animation-duration: 4s;
  animation-iteration-count: 2;
 }
</style>

animation-direction: normal;
Background color of the target element is changing from RED to BLUE, the element box is being shrunk at the same time. The effect repeats twice.

animation-direction: reverse;
The effect is the opposite of the normal direction: the background color of the animatable element is BLUE, and its width is 10% at the beginning; these properties are RED and 100%, accordingly, at the end. The effect takes place twice.

animation-direction: alternate;
Cycle 1 (and any cycle that is an odd count) is played in the normal direction, and cycle 2 (and any cycle that is an even count) is played in the reverse direction, so the background color and width of the element will change as [RED, 100% BLUE, 10%]cycle1 [BLUE, 10% RED, 100%]cycle2.

animation-direction: alternate-reverse;
Cycle 1 (and any cycle that is an odd count) is played in the reverse direction, and cycle 2 (and any cycle that is an even count) is played in the normal direction, so background color and width will change as [BLUE, 10% RED, 100%]cycle1 [RED, 100% BLUE, 10%]cycle2.

So far animation effects created in previous examples disappear when the last keyframe stops. To define an element's look and behaviour before or after animation the developer should employ the animation-fill-mode property. Default value is none: animation rules will not affect the target element before the starting point; neither will they be applied to the element after the last effect finishes. There are three more values that can be used to override the default fill mode. If the value is backwards, the browser will apply the first keyframe declaration immediately, even if animation delay is greater than 0. Compare:

<style type="text/css">
 @keyframes demo {
  0% {background-color: red;}
  100% {background-color: blue;}
 }
 #element1 {
  animation-name: demo;
  animation-delay: 2s;
  animation-duration: 4s;
  animation-fill-mode: none;
 }
 #element2 {
  animation-name: demo;
  animation-delay: 2s;
  animation-duration: 4s;
  animation-fill-mode: backwards;
 }
</style>

Let's assume target elements do not have any explicitly specified background at first. Then the same keyframe rule is applied to both of them. The first element will display no background color during 2 seconds until animation starts. The second element will have the red background since the very beginning irrespective of delay: this is the result of assigning the backwards value to the fill mode.

Another value is forwards: it causes the last existing keyframe to be displayed after all animations are completed. In the example below, the target element will keep its blue background:

<style type="text/css">
 @keyframes demo {
  0% {background-color: red;}
  100% {background-color: blue;}
 }
 #animatable {
  animation-name: demo;
  animation-duration: 4s;
  animation-fill-mode: forwards;
 }
</style>

If the value of the animation-fill-mode property is both, declarations for the first keyframe will be applied regardless of delay, and the last effect will remain on the screen, too. The target element in the example below will have the red background before the animation starts and retain the blue one after all animations stop:

<style type="text/css">
 @keyframes demo {
  0% {background-color: red;}
  100% {background-color: blue;}
 }
 #animatable {
  animation-name: demo;
  animation-delay: 2s;
  animation-duration: 4s;
  animation-fill-mode: both;
}
</style>

Animation effects are not arbitrary: like transitions, CSS animations undergo changes according to a specified timing function. Supported functions used as values of the animation-timing-function property are

  • ease (equivalent to cubic-bezier(0.25, 0.1, 0.25, 1.0));
  • ease-in (equivalent to cubic-bezier(0.42, 0, 1.0, 1.0));
  • ease-in-out (equivalent to cubic-bezier(0.42, 0, 0.58, 1.0));
  • ease-out (equivalent to cubic-bezier(0, 0, 0.58, 1.0));
  • linear (equivalent to cubic-bezier(0.0, 0.0, 1.0, 1.0));
  • steps accepting the number of intervals and the start or end keywords as its parameters;
  • step-start (equivalent to steps(1, start));
  • step-end (equivalent to steps(1, end));
  • cubic-bezier (x1, y1, x2, y2); x1 and y1 are coordinate values of the first point of the curve, x2 and y2 define the second point; valid x values must be in the range [0, 1].

The animation-play-state property controls the flow of animations. A running effect is stopped by setting the property as paused. The running value resumes paused animations:

<style type="text/css">
 @keyframes demo {
  0% {background-color: red;}
  50% {background-color: green;}
  100% {background-color: blue;}
 }
 #animatable {
  animation-name: demo;
  animation-duration: 6s;
 }
</style>
. . .
<script>
setTimeout(
 function() {
  document.querySelector("#animatable").style.animationPlayState="paused";
 },
 2000 // animation will stop in two seconds
);
document.querySelector("#animatable").addEventListener(
 "click",
 function(event) { // resuming animation effect
  event.target.style.animationPlayState="running";
 },
 false
);
</script>

In the example above the target element will change its background color from red to green, then the animation will be paused. After clicking on the element animation will resume, but it will not return to the first keyframe: effect flow will continue and the element will get the blue background.

It is not unusual for CSS modules to have a special shorthand property acting as a substitute for a set of individual properties. The CSS3 Animations module exposes the animation which combines in a single declaration seven properties reviewed above:

<style type="text/css">
 @keyframes demo {
  0% {background-color: red;}
  100% {background-color: blue;}
 }
 #element1 {
  animation-name: demo;
  animation-delay: 1s;
  animation-direction: normal;
  animation-duration: 4s;
  animation-fill-mode: forwards;
  animation-iteration-count: 1;
  animation-timing-function: ease-in;
 }
 #element2 {
  animation: demo 4s ease-in 1s 1 normal forwards;
 }
</style>