Skip directly to content

How I rebuilt "Flying Toasters" using only CSS animations

March 15, 2014

One of my favorite classic screensavers from back in the day was "Flying Toasters," a part of the After Dark bundle.

Ahhh. Those were the good old days.

As a front-end developer, I started wondering if you could recreate the magic using only CSS. The answer, as you probably guessed is, yes, you can (you can see it in action here). Here's how I went about doing it.

Step 1: Get a single toaster to flap using CSS spriting

Getting a character to move isn't new, and one of the classic techniques is to put together a "sprite sheet," which is an image that contains all the individual frames of your animation.

You may have used sprites to capture the hover and active states of your menu buttons, but you can also use them for animations. In my case, I needed an image with the toaster in different phases of flapping. Here's what I came up with:

To give it the appearance of motion, we need to hop rapidly from one frame to another. We do this by creating a box with a fixed width and height and putting in our image as a background image.

<!-- the HTML -->
<div class="toaster"></div>

/* the CSS */
.toaster {
  position: absolute;
  background: url(/sites/default/files/toaster-sprite.gif);
  width: 64px;
  height: 64px;

Now we want to move the position of that background image between each of the sprite frames. We do this by defining some CSS keyframes (you'll want vendor prefixes on many of these rules for cross-browser compatibility, but for the sake of brevity, I'm leaving them out).

 * Our image is 256px wide so this rule tells the image to shift
 * to the right the full length of the image.
@keyframes flap {
  from { background-position:  0px; }
  to { background-position: -256px; }

By themselves, keyframes won't do anything. You need a CSS rule to call them with the animation property. 

/* This runs the animation named 'flap' over a period of 0.4 sec. */
.animated {
  animation: flap 0.4s;

But this won't really work. First, the background image will slide constantly, when what we want it to do is jump: 1st frame, 2nd frame, 3rd frame, 4th frame. Second, the animation will only run once by default, and we want it to run constantly. Finally once the animation runs once, we want it to run once in reverse, so the wings flap back up. You can look up the values that define these behaviors, but here's what it looks like when we add them in:

<!-- update the HTML -->
<div class="toaster animated"></div>

.animated {
  animation: flap .4s steps(4) infinite alternate;

You can see a demonstration of it working in this Codepen embed:

See the Pen CSS Sprite Demonstration by Bryan Braun (@bryanbraun) on CodePen.

Step 2: Fly across the screen with translate()

With the flapping part done, we just need to move it across the screen. The toasters fly from the top-right to the bottom left, and we could choose to animate this by changing the value of z-index or by using a newer function called translate(). According to the fine folks at HTML5Rocks, animating translate() is more performant than z-index, so we'll go with that.

/* Position our toaster just off the screen at the upper right */
.p1 { right: 10%; top: -10%; }

 * Define keyframes to translate it to the bottom left.
 * We'll use -1600px since that will be wider, and certainly taller,
 * than most standard screens.
@keyframes fly {
  from { transform: translate(0, 0); }
  to { transform: translate(-1600px, 1600px); }

/* Update our animation to include our translate() keyframes. */
.animated {
  animation: flap .4s steps(4) infinite alternate, fly 10s linear infinite;

<!-- update the HTML -->
<div class="toaster animated p1"></div>

Now we have a single flying toaster. Whoo hoo!

Step 3: Add in some flying toast

But what's a flying toaster without toast?

Animating the toast is easier because it doesn't need to flap. We just get a single image of toast and move it across the screen. In fact, we can borrow the same position and keyframes we defined for the toaster.

/* Set up our toast object */
.toast {
  position: absolute;
  width: 64px;
  height: 64px;
  background-image: url("/sites/default/files/toast1.gif");

 * Toast-specific animation (needed since our toast doesn't flap)
 * Notice that I added a 6s delay, so it comes after the toaster.
.tst1 {
  animation: fly 10s 6s linear infinite;

<!-- Toast HTML -->
<div class="toast tst1 p1"></div>

As you can see, the code is very similar to that of the toaster.

Step 4: More toasters! More toast!

With all the hard work done, we just need to throw a whole bunch more toasters and toast in there.

We want them to come onto the screen from all different places, so we'll define several more starting positions (similar to .p1 & .p2).

.p6 { right: -2%; top: -10%; }
.p7 { right: 10%; top: -12%; }
.p8 { right: 20%; top: -18%; }
.p9 { right: 30%; top: -13%; }
.p10 { right: 40%; top: -17%; }
/* etc. */

We'll want a few waves of toasters to keep the screen covered while we wait for the first round to repeat again, so we'll add more animations (which I'll call .t1.t2, etc.) with a starting delay on them. We also want toasters flying at different speeds and ones with wings flapping out of sync with the other toasters. For that, we'll define even more animations with various adjustments to the properties.

.t1 {
  animation: flap .2s steps(4) infinite alternate, fly 10s linear infinite;
.t2 {
  animation: flap .2s steps(4) infinite alternate-reverse, fly 16s linear infinite;
.t3 {
  animation: flap .2s steps(4) infinite alternate, fly 24s linear infinite;
/* etc. */

When it's all done, we have a big stack of toasters and toast, starting at various positions, running various animations:

<div class="toaster t1 p6"></div>
<div class="toaster t3 p7"></div>
<div class="toast tst1 p8"></div>
<div class="toaster t2 p9"></div>
<div class="toaster t1 p10"></div>
<!-- etc. -->

Finally we have it: the flying toasters screensaver.

I've put the source up on Github, if you want to take a look. It's part of a whole set of After Dark screensavers that I've animated with CSS (including Fish, Warp, Rainstorm, Messages, and others). Definitely check them out, if you miss that part of the 90s.


Hi, I had After Dark on my PC and remember Mickey Mouse wielding a flashlight, i.e. the screen was dark and the flashlight uncovered parts of it. (Many years later in Windows XP you could see that same flashlight swinging in Explorer's right pane, when you're waiting for a folder to refresh.)

Cool! I remember seeing that animated flashlight in Windows but I didn't know you could trace it back to After Dark.

Fantastic work! The animations look perfect

Thanks for the lesson. What's a good resource for CSS methods?

I tend to pick up bits and pieces from a lot of places. If you're looking for fundamentals, check out A Beginner's Guide to HTML and CSS. The Smaccs book is good for advanced CSS architecture and Chris Coyier's blog CSS Tricks is very good as well. If podcasts are your thing, then I'd recommend The Web Ahead, by Jen Simmons.

As far as references go, the Web Platform Docs on CSS are starting to get really comprehensive, with some great tutorials as well, so I'd definately check that out.

Awesome work, congrats!! CSS is super fun!!

Very well explained, thanks!

need lawnmower man!

Yep, lawnmower man! Loved the growing grass and flowers that he'd cut off indiscriminately. Both lawnmower and globe had memory leaks that'd crash Win95 overnight. Ah, the good old days.

Great and touching work. I liked the After Dark screensaver a lot back in the day and in addition I am happy to learn something about animated CSS sprites. Bookmarked, liked and a big thank you.

Glad you liked it. I glossed over some of the details, but you can find more information about CSS Sprites in the code comments of the Codepen I embedded.

Please do the Bill the Cat screen savers. :D

Bryan - Thank you for giving something from my early IT days a new lease of life..
Can't wait for the rest of the screen savers to be added... please

This was a very helpful post and I really enjoyed it. Thank you.

THX a lot from bringing back to good old days when when men were real men, women were real women and green furry creatures from Alpha Centauri were real green furry creatures from Alpha Centauri ... now you only need to implement a tweak to turn the toasts lighter or darker brown

Any plans to add sound?

Maybe... if there's interest. Especially if somebody knows where I can dig up the sound files.

I've got the CD

When are you gonna package this as a usable screen saver? I had a work flying toasters SS until a few OS updates back.

You may want to look into Websaver, which is some open source software you can download for free. I haven't tried it, but it ought to let you specify a Webpage you want display on the screen as your screensaver. Just point it to one of the demo pages for this project and you'll be in business. :)

Oh the memories! That hit me hard in the nostalgia man!

My startup is making a product that can display that web page as your screensaver, it's called Screensaver Ninja, and it'll be available for both mac and windows. You can find out more at I already have your flying toasters as my screensaver! :D

Any idea how your fantastic project can be transferred to a windows screensaver?

Hmmm, I can't think of anything off the top of my head. Maybe look into, which J. Pablo Fernandez mentioned above?

Oh man this is really fantastic. I loved After Dark and you did such an amazing job animating the toasters! My favorite module they had was an MS-DOS screen saver that made it look like I was sitting there running DOS on my Mac–– Truly puzzling anyone who walked by knew anything about computers. I have tried to figure out how to bring it back for my current computer, but i am just not techie enough to make it happen. What I really want is an MS-DOS app to run on my iPhone and iPad––that should really get people wondering!