You have already rated this page, you can only rate it once!

In this article you'll learn what you need to know to get started with CSS3 animations.

"Animating" with CSS used to be limited to hovering effects. With :hover and :focus pseudo classes we've been able to change color, size, background-color, position, and many other CSS properties based on user action. The :hover trick provides only two states - hovered and non-hovered - with only two keyframes: start and end, and no tweening between these states, creating a harsh and sudden transition. This isn't really animation.

CSS3 transitions solved the tweening issue, enabling transitioning from non-hovered to hovered style (and back) over a period of time. Vendor-prefixed transitions are well supported in modern browsers (starting with IE10 and Firefox 4.0). With transitions, we can create limited simple animations with two keyframes - a start and finish point - and to a single iteration. Most developers have been overcoming these limitations by using JavaScript to animate. With increased support of CSS3 animations, it's time to rely less on JavaScript and animate natively with CSS.

Note that animations are currently supported, prefixed with -webkit- and -moz-, in Chrome, Safari 4+, Firefox 5+, Android Chrome, and iOS webkit.

Keyframes

To animate elements you first need to define a keyframe animation. Then you apply that animation to the elements you want to animate. The first step is to define your animation, which you can attach to an infinite number of elements. Animations are similar to transitions except they provide for more granular control. The minimum required to define an animation is an animation name, a starting point or keyframe and an ending point or keyframe.

@keyframes flapping { from { background-size: 100px 100px; } to { background-size: 20px 100px; } }

In the above code, we've declared the animation name, a starting keyframe and an ending keyframe. If you're using an appropriate browser, you can click on the button to see the animation in action:

Live demo

While in the above animation, we've used the from and to keyterms. We could also have used percentages, which is generally what you will want to use.

@keyframes flapping { 0% { background-size: 100px 100px; } 100% { background-size: 20px 100px; } }

A few things to remember when declaring animations:

Don't forget the %

When it comes to lengths, like px and ems, 0 is 0. Note in animation declarations. Don't forget the % unit of measurement.

When it comes to lengths, like px and ems, 0 is 0. Note in animation declarations. Don't forget the % unit of measurement. Don't forget the 100%, or final to keyframe declaration

While the 0% and 100% are not required by the specifications, they need to be included for current browser implementations.

While the 0% and 100% are not required by the specifications, they need to be included for current browser implementations. Don't quote the animation name

Although quoting the animation provides for more legible markup, adding quotes to the name in incorrect according to W3C draft specifications, and will make the animation fail in Firefox.

One of the features that makes keyframe animation more powerful than transitions is the ability to control the animation on a granular level. For example, the rainbow animation below has 11 keyframe blocks:

@keyframes rainbow { 0% {background-color: #FF0000;} 10% {background-color: #FF8000;} 20% {background-color: #FFFF00;} 30% {background-color: #80FF00;} 40% {background-color: #00FF00;} 50% {background-color: #00FF80;} 60% {background-color: #00FFFF;} 70% {background-color: #0080FF;} 80% {background-color: #0000FF;} 90% {background-color: #8000FF;} 100% {background-color: #FF0080;} }

Live demo

Had we used CSS transitions to go from #FF0000 to #FF0080, we would have transitioned from red to magenta, showing only colours in the red spectrum. With animation keyframe granular control, our animation goes from red to pink by going through the colour spectrum.

We can include as many animatable properties as we want to animate in any keyframe block. See the example below.

@keyframes rainbowdimmer { 0% {background-color: #FF0000; opacity: 1;} 20% {background-color: #FFFF00;} 40% {background-color: #00FF00;} 50% {opacity: 0;} 60% {background-color: #00FFFF;} 80% {background-color: #0000FF;} 100% {background-color: #FF0080; opacity: 1;} }

Live demo

In this example, opacity will change from opaque to transparent and back opaque, while the colour will go through the spectrum. Note that we didn't need to declare every property in every keyframe block. Rather, we only included properties when that property needed a keyframe definition.

Note that duplicate keyframe selectors are not supported:

100% {background-color: #FF0080;} 100% {opacity: 1;}

When two keyframe blocks have the same selector, as per the cascade, the last block overrides previously declared blocks. Had we written the above, the first line would be ignored, overridden by the second line, which has the same keyframe selector value.

On the other hand, if you have an animation that has duplicate keyframes, you don't have to declare the same block twice. Instead, separate the selectors of the duplicate keyframes with a comma. Note that the order of the declarations doesn't matter (100% can come before 0%). In the butterfly example, we want to start and end our butterfly movement animation with the butterfly in the exact same location. Instead of declaring two separate code blocks, we simply separate the first and last keyframe selectors with a comma:

@keyframes movement { 0%, 100% { top: 0; left: 0; } 25% { top: 0; left: 100px; } 50% { top: 100px; left: 100px; } 75% { top: 100px; left: 0; } }

Live demo

When creating a bouncing ball animation, at every bounce the ball is at the bottom of the container.

We declare three of the four 'bottom' keyframes together, since the final keyframe includes more than one property. You can only use comma-separated duplicate keyframes when all the property/values in the keyframe block are the same.

@keyframes bouncing { 40%, 70%, 90%{ animation-timing-function: ease-out; bottom: 0; } 0% { bottom: 200px; left: 0; animation-timing-function: ease-in; } 55% { bottom: 50px; animation-timing-function: ease-in; } 80% { bottom: 25px; animation-timing-function: ease-in; } 95% { bottom: 10px; animation-timing-function: ease-in; } 100% { left: 110px; bottom: 0; animation-timing-function: ease-out; } }

Live demo

Note that we had two properties being animated. We moved the ball up and down numerous times with granular control. The left to right motion, however, was smooth, and therefore only needed two keyframe declarations. We've also changed the animation timing function to make the bounce look smooth and natural. We'll discuss the animation timing function part of this animation below, but the important thing to note is that the animation-timing-function is the only animation property that can be included within keyframe declarations. The W3C has an incomplete list of properties that are animatable, see the list below. We can include the animation timing function to define how the animation moves to the next keyframe. Without it, our bouncing ball animation above was very jumpy.

Animatable properties: background-color, background-position, border-bottom-color, border-bottom-width ,border-left-color ,border-left-width, border-right-color, border-right-width, border-spacing, border-top-color, border-top-width, bottom, clip, color, font-size, font-weight, height, left, letter-spacing, line-height, margin-bottom, margin-left, margin-right, margin-top, max-height, max-width, min-height, min-width, opacity, outline-color, outline-width, padding-bottom, padding-left, padding-right, padding-top, right, text-indent, text-shadow, top, vertical-align, visibility, width, word-spacing, z-index.

Vendor prefixing

The animations above won't actually work everywhere, especially with browsers that weren't recently updated, with them it'll be necessary to use vendor prefixes. In this case we'll have to declare the @keyframes three times: with -moz- for Firefox 5+, with the -webkit- prefix for Safari, Chrome and the various mobile webkit browsers and last, without any prefixes, for when browsers support the vendor-neutral syntax.

/* for Webkit browsers */ @-webkit-keyframes flitter { 0%{ -webkit-transform: scale(1, 1); } 100% { -webkit-transform: scale(0.2, 1); } } /* for Firefox */ @-moz-keyframes flitter { 0%{ -moz-transform: scale(1, 1); } 100% { -moz-transform: scale(0.2, 1); } } /* for browsers supporting vendor-less syntax */ @keyframes flitter { 0%{ transform: scale(1, 1); } 100% { transform: scale(0.2, 1); } }

In this example, we've added the vendor prefixing in front of the 'keyframes' keyword, and also for the transform property, as vendor-less transforms are supported only by recently updated browsers.

Animating elements

Now that we have animations declared, we can animate elements on our page by attaching animations to them. We need to at least provide the element with the animation name and duration. There are many other properties that enable us to control the appearance of animations, but the name and duration are required.

Let's start defining our butterfly:

.butterfly { height: 100px; width: 100px; position: absolute; top: 50px; left: 50px; background-image: url(butterfly.png); }

animation-name and animation-duration

Our first goal is to make the butterfly flitter. To apply an animation we provide the element with the name of the animation to use and the duration of that animation. For that we have two properties: animation-name and animation-duration. The animation-name property accepts a comma separated list of unquoted animation names. These are the user defined names you defined in your @keyframes rule. So far in the examples above, we can include flapping, flitter, rainbow, rainbowdimmer and bouncing.

In addition to adding the animation name(s), we have to define how long the animations should last in seconds(s) or milliseconds (ms). Add the length of time it takes for the animation to iterate once from 0% to 100% with the animation-duration property. The minimum duration is 1ms. In our flapping example, we have been using 500ms, or 0.5s, in the above examples.

.butterfly { -webkit-animation-name: flitter; -webkit-animation-duration: 500ms; -moz-animation-name: flitter; -moz-animation-duration: 500ms; animation-name: flitter; animation-duration: 500ms; }

Live demo

Our butterfly isn't flitting (or fluttering?). By default, animations only iterate through once. To make it flit several times, or forever, we can add the animation-iteration-count property. The value of which is either an integer or the key term infinite. The default value is 1.

.butterfly { -webkit-animation-name: flitter; -webkit-animation-duration: 500ms; -webkit-animation-iteration-count: infinite; -moz-animation-name: flitter; -moz-animation-duration: 500ms; -moz-animation-iteration-count: infinite; animation-name: flitter; animation-duration: 500ms; animation-iteration-count: infinite; }

Live demo

The animation above is annoying not just because it won't stop, but because the animation goes from 0% keyframe to 100% over 500ms, but then jumps back to 0%. It scales over time from 100px wide to 20px wide, then jumps back to 100px as it starts its next iteration. The default process is for an animation to iterate from 0% to 100% over time, then to jump back to 0% to start the next iteration.

Sometimes you want animations to behave like transitions: when you transition on hover, the animation reverses on mouse out. With the animation-direction property, every other animation can be set to go from 100% to 0%. While a bouncing ball goes only in one direction, always going from 0% to 100%, the flitting of a butterfly is a good example of the need for alternating the direction of the animation. Let's add it to our butterfly:

.butterfly { -webkit-animation-name: flitter; -webkit-animation-duration: 500ms; -webkit-animation-iteration-count: 40; -webkit-animation-direction: alternate; -moz-animation-name: flitter; -moz-animation-duration: 500ms; -moz-animation-iteration-count: 40; -moz-animation-direction: alternate; animation-name: flitter; animation-duration: 500ms; animation-iteration-count: 40; animation-direction: alternate; }

Live demo

We can fine-tune our animation further by setting animation timing functions to control how these intermediate values are computed over time. The default value is ease but most animal motions really ease in and out over time. We add the ease-in-out value to our animation timing function.

.butterfly { -webkit-animation-name: flitter; -webkit-animation-duration: 500ms; -webkit-animation-iteration-count: 40; -webkit-animation-direction: alternate; -webkit-animation-timing-function: ease-in-out; -moz-animation-name: flitter; -moz-animation-duration: 500ms; -moz-animation-iteration-count: 40; -moz-animation-direction: alternate; -moz-animation-timing-function: ease-in-out; animation-name: flitter; animation-duration: 500ms; animation-iteration-count: 40; animation-direction: alternate; animation-timing-function: ease-in-out; }

Live demo

We've also added ease-in and ease-out at different steps in our bounce animation. The animation-timing-function is the only animation property that can be included within keyframe declarations. Include the animation timing function to define how the animation moves to the next keyframe. Without it, our bouncing ball animation above would have been very jumpy.

By default, animation begin immediately when applied. We can control this with the animation delay property. While this is a simple to understand property, there is a cool trick to know about animation-delay. If you want an animation to begin halfway through the animation, include an animation delay value that is negative. For example, if you have a 10s animation, including an animation-delay: -5s; will cause the animation to start immediately, starting half way through the animation.

animation (shorthand)

Animation properties are verbose. Too verbose. Especially with vendor prefixing. Fortunately, there is a shorthand. The shorthand must include the name and duration of the animation. If you are including a delay, make sure the duration comes first! The order is generally:

animation: <name> <duration> <timing-function> <delay> <iteration-count> <direction> <fill-mode>;

We can write the animation above in three much simpler lines:

.butterfly { -webkit-animation: flitter 500ms ease-in-out 5s 40 alternate; -moz-animation: flitter 500ms ease-in-out 5s 40 alternate; animation: flitter 500ms ease-in-out 5s 40 alternate; }

Live demo

A single element can have multiple animations at the same time. We have a flittering butterfly, but it's not going anywhere. Let's make it move around the box as if it were actually flying.

.butterfly { -webkit-animation: flitter 300ms ease-in-out 1s 40 alternate, movement 5s linear 2s; -moz-animation: flitter 300ms ease-in-out 1s 40 alternate, movement 5s linear 2s; animation: flitter 300ms ease-in-out 1s 40 alternate, movement 5s linear 2s; }

Live demo

Always consider the duration and interaction counts of the animations to time your animations well. Also consider what properties are being animated. While we can apply as many animations as we want to an element, we can only apply a single occurrence of a property at a time. In other words, while we may have four animations that we want to attach to an element, we can only apply one transform and one top/left position value at a time.

.butterfly { -webkit-transform-origin: -10px -10px; -moz-transform-origin: -10px -10px; transform-origin: -10px -10px; -webkit-animation: flapping 300ms ease-in-out 1s 40 alternate, bouncing 10s ease-in-out 1s, rotation 0.5s ease 24 1s alternate; -moz-animation: flapping 300ms ease-in-out 1s 40 alternate, bouncing 10s ease-in-out 1s, rotation 0.5s ease 24 1s alternate; animation: flapping 300ms ease-in-out 1s 40 alternate, bouncing 10s ease-in-out 1s, rotation 0.5s ease 24 1s alternate; }

Live demo

We added transform-origin to make the rotation appear more random and natural. Also note that we have three animations ending at 13, 11 and 13 seconds respectively. When including multiple animations, consider their timing relative to each other.

Our butterfly nicely floats down the page, but jerks back up to the top left when the bouncing animation is complete. With the animation-fill-mode property we can tell the butterfly to stay at the bottom right when the animation ends.

The animation-fill-mode takes one of four values: backwards, forwards, none or both, with default being none. The value of backwards makes the element go directly to keyframe 0% when the page loads, even if there is an animation-delay, staying there until the animation starts.

The value of forwards tells the browser to stop the animation on the last keyframe at the end of the last iteration and not revert back to its pre-animation state.

The value of both applies both backwards and forwards, sitting on the first keyframe until the animation begins (no matter the length of the positive animation delay) and staying on the last keyframe at the end of the last animation. This is what we want for our bounce:

.butterfly { -webkit-transform-origin: -10px -10px; -moz-transform-origin: -10px -10px; transform-origin: -10px -10px; -webkit-animation: flapping 300ms ease-in-out 1s 40 alternate, bouncing 10s ease-in-out 1s both, rotation 0.5s ease 24 1s alternate forwards; -moz-animation: flapping 300ms ease-in-out 1s 40 alternate, bouncing 10s ease-in-out 1s both, rotation 0.5s ease 24 1s alternate forwards; animation: flapping 300ms ease-in-out 1s 40 alternate, bouncing 10s ease-in-out 1s both, rotation 0.5s ease 24 1s alternate forwards; }

Live demo

Pausing and playing animations

In addition to pausing on the first and last keyframes with animation-fill-mode, we can pause along the way with the animation-play-state. By default, all animations are running, but they can be paused:

.butterfly:hover { -webkit-animation-play-state: paused; -moz-animation-play-state: paused; animation-play-state: paused; }

To see this hover declaration in action, simply hover over any animating butterfly above.

We've walked through a very simple animation. This is just to show what is possible. CSS animations are very powerful, providing a way of animating without the use of JavaScript, while providing event handlers should JavaScript events be necessary.

It is important to remember that just because animation is possible, does not mean that it is always a good idea. Use animation judiciously. We don't want to return to the animated GIF state of the late 1990s, or the abundance of Flash intros look of the early 2000s.

Remember: just because you can, doesn't mean you should!

Source: www.creativebloq.com