Key Takeaways
- CSS3 animation allows for transitioning between CSS properties along a timeline, providing a fundamental tool for creating animations such as bouncing balls, spinning tires, or launching rockets.
- CSS3 keyframes can be used to create cel or sprite animation, where each moment in the timeline is drawn as a standalone image and then displayed rapidly in succession to create the illusion of movement.
- The seamless loop for animations can be achieved by creating a jagged timeline where each new frame is snapped into place so quickly that the in-between state is not visible, creating a natural and fluid animation.
- CSS3 animation can be used to create complex, organic animations by weaving together different timings, creating effects such as sunlight, water, and clouds, or in this case, a flickering flame. The animation can be made more interesting by offsetting each element slightly from its siblings, allowing the edges to mingle and interact.
CSS3 Animation Basics
If you haven’t used CSS3 animations yet, here’s a crash course. If you’ve already got some familiarity with CSS3 keyframes, jump to “Working with CSS3 Sprites.” To keep things breezy to read, I’m going to use the official “unprefixed” W3C syntax (i.e. @keyframe) throughout this article, but you’ll need to use the browser-specific prefixes (i.e. @-webkit-keyframe, @-moz-keyframe, @-ms-keyframe, etc.) to see it working in real-world browsers. The core concept behind CSS3 animation is to let you transition between CSS properties. Like all animation, CSS3 needs a timeline with a start and a finish — set at 0% and 100% respectively. The code for the simplest of animation timelines would look like this:@keyframes mysimpleanimation {
0% {background-color:#f00;}
100% {background-color:#00f;}
}
As you might guess, the above animation is designed to change a red background to blue. However, by itself, this code won’t do anything until we apply it to an HTML object on screen. We also need to set the time length of the animation (in seconds).
Here’s how to include a time length within your CSS:
#example {
...
animation: mysimpleanimation 4s infinite;
}
Here’s that simple example in action.
We’re free to create as many points along the timeline as we’d like — for instance we can change our animation to green (#0f0) at the halfway point by adding the following line:
@keyframes mysimpleanimation {
0% {background-color:#f00}
50% {background-color:#0f0}
100% {background-color:#00f}
}
There are a slew of other well-documented attributes and settings, but we’ve covered the fundamentals you’ll need for now.
Working with CSS3 Sprites
Note: For all the demos in this article, I’m going to be using Lea Verou’s super-lovely Dabblet webapp. Apart from looking luscious and being hard-wired straight into Github, Dabblet will let you fiddle with the CSS here and see the results in real-time. The other great feature of Dabblet is that it let’s you write plain, unprefixed CSS3 while magically adding the browser-specific code in the background (using Lea’s “-prefix-free“). This is brilliant for keeping the code examples simple to read, but be aware that you’ll need to add the “-moz,” “-webkit,” and “-ms” prefixes to make this code work outside of Dabblet. So, despite only really having one good trick — transitioning between CSS properties along a timeline — CSS3 keyframes give you many of the basic building blocks of animation including:- Squash and stretch (in CSS: width, height)
- Rotation (transform:rotate)
- Position in space (left, right, top & bottom)
- Color and opacity changes (color, background-color, opacity)
- a wriggling snake
- flapping wings
- a spinning earth
- a running man
The Setup
Here’s the basic HTML framework that I’m starting with:
I’m using a container <div> (#logfire) to hold the background graphic and a placeholder <div> (#flamegroup) that will hold our flames in position. Inside the placeholder I’ve nested a third <div> (.flame) that will become our flame.
I’ve embedded the flame graphic into the background-image, but we’re cropping off most of the image, only allowing the left-hand flame to show.
.flame {
width:100px;
height:136px;
background:url(flame.png) left top no-repeat}
Here’s our starting code.
Setting Up Our Timeline
To make a seamless loop, we’ll need to create a 4-frame loop — that is, we’ll show frames 1,2,3, and 2 again, and repeat. We could represent that sequence along our invisible timeline as positions 0%, 25%, 50%, 75% and 100% (i.e. back to frame 1). At each stage we reposition our background at the next frame, so our CSS might look something like this:@keyframes flicker { /* flame pulses */
0% {
background-position:0px 0px;
}
25% {
background-position:-100px 0px;
}
50% {
background-position:-200px 0px;
}
75% {
background-position:-100px 0px;
}
100% {
background-position:0px 0px;
}
}
Then, we could attach our “flicker” animation to our flame class and set it to loop every 1.1 seconds:
.flame {
...
animation: flicker 1.1s infinite;
}
Fantastic! Except for the part where it doesn’t look quite right.
As the above example shows, it animates too nicely, gracefully sliding between frames. Just like those little page-flick animations you used to make in the corners of book pages, the magic lies in snapping each new frame into place so quickly that you can’t see the in-between state.
Our new jagged timeline now looks like this:
@keyframes flicker { /* flame pulses */
0% {
background-position:0px 0px;
}
25% {
background-position:0px 0px;
}
25.1% {
background-position:-100px 0px;
}
50% {
background-position:-100px 0px;
}
50.1% {
background-position:-200px 0px;
}
75% {
background-position:-200px 0px;
}
75.1% {
background-position:-100px 0px;
}
100% {
background-position:-100px 0px;
}
}
As you can see, our first cell stays motionless from 0%-25%. Then suddenly at 25.1% along the timeline, we crank the background 100 pixels to left. Again we leave it there till the 50% mark before cranking it left again at 51.1%.
I think you get the idea.
If we plug that CSS into our example we now get a pleasantly wiggling flame.
Add a Pulse
Flames don’t just move, they vary mildly in intensity. Since we already have the timeline set up, why not tweak the opacity a little to give it a subtle pulse?@keyframes flicker { /* flame pulses */
0% {
background-position:0px 0px;
opacity:.8
}
25% {
background-position:0px 0px;
}
25.1% {
background-position:-100px 0px;
}
50% {
background-position:-100px 0px;
opacity:.4
}
50.1% {
background-position:-200px 0px;
}
75% {
background-position:-200px 0px;
}
75.1% {
background-position:-100px 0px;
}
100% {
background-position:-100px 0px;
opacity:.8
}
}
Here’s the result.
A decent result, but let’s face it: We could get something pretty close to this with a good animated .gif file. Let’s ratchet things up a little.
Fan those Flames
Circling back to our original HTML, we’re going to add more flame elements — lucky we have that handy holder <div>, huh? Let’s add two more <div> elements with the “flame” class to our “flamegroup.” We’ll also give each <div> it’s own ID so we can target them separately.
We now have three flame elements, but since they’re dancing in perfect unison, they still look like a single flame. Let’s delete the animation from the “flame” class and add it to our new IDs.
#fl1 {
-webkit-animation: flicker .7s infinite;
}
#fl2 {
-webkit-animation: flicker .7s infinite;
}
#fl3 {
-webkit-animation: flicker .7s infinite;
}
Now we are free to call the same animation (i.e. “flicker”), but we’ll give each one a different timing to keep things interesting. Riffing on the prime number idea that we used in the cicada principle article, I’m going to set the flame elements to loop in 0.7, 1.1 and 1.3 seconds respectively (yes, I know they’re not primes).
Finally, rather than stacking them precisely on top of each other, I’m going to offset each flame slightly (10-20px) from its siblings. This is mainly so we can see the edges mingle and interact.
Here’s the CSS:
#fl1 {
animation: flicker 1.3s infinite;
top:-10px; /* offset */
left:10px /* offset */
}
#fl2 {
animation: flicker .7s infinite;
top:10px; /* offset */
left:20px /* offset */
}
#fl3 {
animation: flicker 1.1s infinite;
}
And here’s the final demo in action.
Our flames jump, dance and weave in a soft, less “GIF-loopy” manner. Sometimes you think you have the pattern nailed but then it seems to shift. Dabblet lets you tinker, so feel free to play with the timing. Obviously the slower the loop, the longer between exact pattern repeats.
There are a few points to be aware of:
- As I mentioned earlier, the Dabblet examples use “-prefix-free” to let us write clean, unprefixed CSS3, but you’ll need to add the “-moz,” “-webkit,” and “-ms” prefixes to make this code work outside of Dabblet.
- I wanted to keep things relatively simple for the example, but we could easily spice things up a little more by setting background-size height to 100%, and then animating the height of our flame <div>. This would make our flames leap and dive more energetically.
- Obviously, older browsers won’t support CSS3 animation, but Modernizr.com allows you to target those browsers with a fallback. For older browsers, rendering the flames statically seems to be a perfectly acceptable option. In fact, it’s hard to imagine how an IE8 user would ever become aware that other users were seeing an animation.
- You may sometimes see a slight “jog” or flicker randomly in the animation. It seems to be a browser buffer overflow bug, but so far I haven’t found a way to eliminate it, although slower computers seem to make it worse.
Summing Up…
I think this idea of weaving together animation timings has some interesting potential, so watch this space in the coming weeks for some more experiments. Subtle sunlight, water, and clouds effects come to mind. So, what do you think? And if you have any ideas of your own, make a Dabblet and share them here. UPDATE: March 1st, 2012 Reading up on the CSS animation spec, I’ve found there’s a better way to control the sprite switching. The @keyframe syntax has a reasonably rarely-used attribute called ‘step’ that allows you to control how many ‘inbetween’ animation states are generated by the browser. It looks like this in it’s unprefixed state:animation: animation_name 1.1s steps(3) infinite;
This code would generate three stages in-between the steps that we’ve manually set out in our @keyframe code.When using sprites, we don’t want show ANYTHING between changing sprites so we just set our steps to 1.
animation: flicker 1.1s steps(1) infinite;
This allows us to greatly simplify our flame timing loop. Here’s an updated Dabblet showing it working.
Frequently Asked Questions about Organic CSS3 Animation
What is Organic CSS3 Animation?
Organic CSS3 Animation is a technique that uses CSS3 properties to create natural, smooth, and fluid animations. This technique leverages the power of CSS3 transitions and transforms to animate HTML elements without the need for JavaScript or jQuery. The animations created using this method are more efficient and smoother as they are handled by the browser’s native rendering engine.
How can I create a cycling slideshow using Organic CSS3 Animation?
Creating a cycling slideshow using Organic CSS3 Animation involves using keyframes and the animation property. You can define different stages of the animation using keyframes and then apply these keyframes to an element using the animation property. The slideshow effect can be achieved by animating the opacity or position of the slides.
Why are my CSS3 animations not smooth?
If your CSS3 animations are not smooth, it could be due to a number of reasons. One common issue is using properties that trigger layout recalculations, such as width, height, left, and top. Instead, try to use properties like transform and opacity that do not cause layout recalculations. Also, ensure that your animations are running at a consistent frame rate.
How can I make my CSS3 animations loop infinitely?
To make your CSS3 animations loop infinitely, you can use the infinite keyword in the animation property. For example, animation: slide 5s infinite;
will make the slide animation loop forever.
Can I use Organic CSS3 Animation to animate SVG elements?
Yes, you can use Organic CSS3 Animation to animate SVG elements. The process is similar to animating HTML elements. You can use keyframes to define the stages of the animation and then apply these keyframes to the SVG elements using the animation property.
How can I control the speed of my CSS3 animations?
The speed of CSS3 animations can be controlled using the animation-duration property. This property specifies how long an animation should take to complete one cycle. For example, animation-duration: 2s;
will make the animation complete in 2 seconds.
Can I use Organic CSS3 Animation on a responsive website?
Yes, Organic CSS3 Animation can be used on a responsive website. The animations will adapt to the screen size and resolution of the device. However, you may need to adjust the animation properties for different screen sizes using media queries.
How can I pause and resume a CSS3 animation?
You can pause and resume a CSS3 animation using the animation-play-state property. This property can have two values: running and paused. For example, animation-play-state: paused;
will pause the animation.
Can I animate multiple properties at once using Organic CSS3 Animation?
Yes, you can animate multiple properties at once using Organic CSS3 Animation. You can specify multiple properties in the keyframes and they will be animated simultaneously.
How can I create a bouncing effect using Organic CSS3 Animation?
To create a bouncing effect using Organic CSS3 Animation, you can use the cubic-bezier timing function. This function allows you to create custom easing effects, including a bouncing effect. You can specify the cubic-bezier function in the animation-timing-function property.
Alex has been doing cruel and unusual things to CSS since 2001. He is the lead front-end design and dev for SitePoint and one-time SitePoint's Design and UX editor with over 150+ newsletter written. Co-author of The Principles of Beautiful Web Design. Now Alex is involved in the planning, development, production, and marketing of a huge range of printed and online products and references. He has designed over 60+ of SitePoint's book covers.