HTML5 and CSS3: Animation without Flash or JavaScript

Ryan Boudreaux demonstrates the @keywords property in HTML5 and CSS3 that allows you to create animations without the use of Flash or JavaScript.

In a previous post, I touched on the Canvas element and primarily reviewed the 2D capability of the element; today, I will touch on the CSS3 animations as specified in the W3C CSS Animations Module Level 3, and in particular, animation capabilities utilizing several HTML5 elements and CSS3 styles and properties. Utilizing a combination of @keyframes, transform, translate, radial-gradient, repeating-linear-gradient, animation name, animation timing function, and animation duration, we will also create some incredible 3D effects without the use of any Flash or JavaScript.


@keyframes draws its origins from the term key frame, which in animation and filmmaking is a drawing that defines both the starting and ending points for a smooth transition. According to Wikipedia, keyframing is the animation technique where every keyframed computer animation is directly modified or manipulated by the creator, such that no tweening has actually occurred. This method is similar to the drawing of traditional animation, and is chosen by artists who wish to have complete control over the animation.

Currently the @keyframes styling rule is not supported in any browsers, however Firefox supports the -moz- prefix with the @-moz-keyframes rule, Safari and Chrome support the -webkit- prefix with the @-webkit-keyframes rule, and the -ms- prefix for Internet Explorer 8+ with the @-ms- webkit-keyframes rule. However, as of this writing I have been able to view the examples successfully within the Chrome browser.

In CSS3, the syntax for @keyframes has this basic declaration and usage:

@keyframes { animation_name keyframes-selector {css_styles;} }

And several prefix examples include this ‘from' 0% and ‘to' 100% selector values along with the CSS opacity styles:

@-moz-keyframes animation_name {
        0%   { opacity: 0; }
        100% { opacity: 1; }
@-webkit-keyframes animation_name {
        0%   { opacity: 0; }
        100% { opacity: 1; }
@-ms-keyframes animation_name {
        0%   { opacity: 0; }
        100% { opacity: 1; }

According to the W3C specification, keyframes are specified using a specialized CSS at-rule. A @keyframes rule consists of the keyword @keyframes, followed by an identifier giving a name for the animation (which will be referenced using animation-name), and then is followed by a set of style rules (delimited by curly braces). The keyframe selector for a keyframe style rule consists of a comma-separated list of percentage values or the keywords from or to, more on that later. The selector is used to specify the percentage along the duration of the animation that the keyframe represents. The keyframe itself is specified by the block of property values declared on the selector.

With the @keyframes rule, the animation is created by gradually changing from one set of CSS styles to another, which can be changed many times. The change will occur as specified in percentages or by using the keywords from and to, which is equivalent to 0% and 100%, where 0% is the beginning of the animation and 100% designates when the animation is completed. It is recommended that the percentage selectors from beginning and completion both be defined for best browser support.

Calling the keyframe animation can be accomplished through several properties, and they are listed in this table along with their available values:

Property Available Values
animation-timing-function: ease, ease-out, ease-in, ease-in-out, linear, cubic-bezier(x1, y1, x2, y2)
animation-duration and -delay: Xs or Xms
animation-duration-count: X
animation-fill-mode: forwards, backwards, both, none
animation-direction: normal, alternate

Let's get animated!

In this first example, six keyframes are specified for the animation named "wobble." In the first keyframe of the animation cycle the left value of the animation is 0px. After 25% of the animation duration, the left value has jumped to 50px, at 40% of the animation it has jumped 75px, at 60% of the animation it has dropped to 50px, at 75% of the animation it has returned to the 0px position, then the completion of the animation at 100% it has finished at 25px.

#outer {
position: relative; top: 10px; left: 0px;
@keyframes 'wobble' {
    0%   {left: 0px;}
    25%  {left: 50px;}
    40%  {left: 75px;}
    60%      {left: 50px;}
    75%      {left: 0px;}
    100% {left: 25px;}
#wobble_animation {
      font-size: 14px;
      width:  55px;
      height: 55px;
      position: relative; top: 0px; left: 0px;
      /* Safari and Chrome */
      -webkit-animation-name: wobble;
      -webkit-animation-duration: 6s;
      -webkit-radial-gradient(red 12px, transparent 24px),
      -webkit-repeating-linear-gradient(45deg, red 5px,  green 2px, yellow 5px, blue 2px, transparent 14px,
                                    red 4px, blue 4px, transparent 4px, transparent 12px);
      animation-name: wobble;
      animation-duration: 6s;

(Note: the prefix examples -moz- and -ms- have been omitted here, however, all the code examples referenced in this post can be found in the download file below.)


<div id="outer">

<div id="wobble_animation">Wobble</div>


Figure A shows the animation frames as rendered in Chrome 15.0.8 (with screen captures for each keyframe cycle of the six second duration). Click here to download the file for the live demonstration in Chrome.

Three-dimensional example

This second example will demonstrate a 3D effect using @keyframes, with transform and translate, in addition to radial-gradient, repeating-linear-gradient, box-shadow, animation-name, and animation-duration to set this 14 second animation in motion. The @keystone cycle starts at -15 degree rotation with a 25 degree skew and between 0% and 20% it cycles to a -35 degree rotation with a 4 degree skew, between 20% and 45% it cycles into a -15 degree rotation with a 25 degree skew, between 40% and 60% the cycle transitions to a 45 degree rotation with a -75 degree skew, between the 60% and 80% cycle the object transitions to a 10 degree rotation and a -15 degree skew, and the final cycle from 80% to 100% finished with a 0 rotation and 0 skew.

@-webkit-keyframes ThreeDimension {
   0% {-webkit-transform: translate(0px,0) rotate(-15deg) skew(25deg,0);}
   20% {-webkit-transform: translate(100px,0) rotate(-35deg) skew(45deg,0);}
   45% {-webkit-transform: translate(200px,0) rotate(-15deg) skew(25deg,0);}
   60% {-webkit-transform: translate(200px,0) rotate(45deg) skew(-75deg,0);}
   80% {-webkit-transform: translate(75px,0) rotate(10deg) skew(-15,0);}
   100% {-webkit-transform: translate(0px,0) rotate(0) skew(0,0);}
#ThreeD_Animation {
font-size: 24px;
width:  250px;
height: 250px;
position: absolute; top: 100px; left: 100px;
  -webkit-radial-gradient(red 48px, transparent 144px),
  -webkit-repeating-linear-gradient(45deg, red 1px,  yellow 4px, green 8px, red 12px, transparent 16px,
                                    blue 20px, red 24px, transparent 18px, blue 12px);
background-size: 250px 250px, 250px 250px;
background-position: 0 0;
-moz-box-shadow: 15px 20px 15px 1px rgba(0,0,0,0.4), 12px 12px 0px 8px rgba(0,0,0,0.4) inset;
-webkit-box-shadow: 15px 20px 15px 1px rgba(0,0,0,0.4), 12px 12px 0px 8px rgba(0,0,0,0.4) inset;
box-shadow: 15x 20px 15px 1px rgba(0,0,0,0.4), 12px 12px 0px 8px rgba(0,0,0,0.4) inset;
-webkit-border-radius: 10px;
border-radius: 10px;
-webkit-animation-name: ThreeDimension;
-webkit-animation-duration: 14s;
<div id="outer">
      <div id="wobble_animation">Wobble</div>
      <p class="bg">"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
      <div id="ThreeD_Animation">3D Animation</div>
Figure B shows the resulting screen captures as rendered in Chrome:

The screen capture images above are compressed for viewing purposes, the live demonstration is much larger and best viewed full screen.

To view all examples demonstrated in this post, click here to download the files, and then open the html file with the Chrome browser.