|Updated

Playing with Fire: Organic CSS3 Animation

Share this article

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.
Mythbusters testing the chinese water torture.
Mythbusters testing the chinese water torture in 2008.
A few years back, I saw a great episode of Mythbusters, where they tested the idea of the Chinese water torture. One by one, Adam, Kari, Scotty and Tory were each firmly secured before being subjected to the slow, rhythmic beat of droplets onto their foreheads. And one by one, each was broken down — in Kari’s case, to the point of tears — in under an hour. It’s not the most comfortable thing to watch, but it offers an obvious take-away: While some rhythms can be soothing, tight repetition can quickly drive us stark-raving mad. Of course, as web people, we already know this intuitively! Who hasn’t experienced the site with the endlessly spinning logo? Who hasn’t been driven to distraction by that industrious little construction worker toiling away behind an “Under Construction” sign? It raises an obvious question: Is it possible to use animation without introducing these mind-torturing loops? Let’s see what we can do.

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)
File a Bugs report?
Traditional cel animation (or perhaps the first Bugs report? #dadjoke)
This covers a lot of potential animation scenarios, from bouncing balls to spinning tires to launching rockets. However, it’s not so obvious how you would, for instance, manipulate CSS properties to make:
  • a wriggling snake
  • flapping wings
  • a spinning earth
  • a running man
Classic cel (or sprite) animation
is one common answer to that problem. We’ve probably all seen the old Disney or Warner Brothers hand-drawn “cartoon cels.” Each moment in the timeline is drawn as a standalone image. Then each cel is displayed rapidly in succession to give the illusion of movement. So, how do we do that with CSS3? Let’s begin with a simple cel animation that we can develop into something more sophisticated. I’m starting with single .png showing a hand-drawn flame over three frames. It won’t be hard to make this image loop seamlessly.
3 frame flame
Our 3 frame flame cel
Each flame cel is 136px high by 100px wide.

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}
The basic scene
The basic static scene
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.
A screenshot — although the static image doesn't do it justice.
A screenshot — although the static image kinda defeats the purpose.
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.
We’ve also seen some evidence of our processor cycles spiking during *some* larger CSS3 animations. It seems to be linked to particular types of animation, but I haven’t isolated the key problem areas yet. Suffice to say, if you hear your CPU fan kick into overdrive, you’ve probably hit on the same issue.

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 WalkerAlex Walker
View Author

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.

CSS3imagerytutorialWeb Design
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week