Creating animation with CSS3, an alternative to Flash (Part 1)

Last month the Interactive Content Team developed the LHSA – HIV/AIDS website and I thought it might be nice to show you how the simple animation of the bus on the home page was created.

Firstly, as the title of this blog post would suggest, it was not created using Adobe Flash (for those of you unfamiliar with this technology read the “brief history of flash” below). This simple animation was created using CSS3, a little HTML code and some jQuery.

It was adapted from an original idea I had to test the capabilities of CSS3 animation, and to see if it could measure up to the capabilities of Flash. I found this really helpful tutorial online by Rachel Nabors (Flashless Animation) and basically took it from there.

This was my starting exercise below:

You can see the idea is pretty simple; I have a bus in the centre of the screen, which gives the impression that it’s moving along the street. However, the bus never moves from its position on the screen. The bus is in fact stationary, only the wheels are moving. The items that are moving are the street scene and background layers. By moving these in the opposite direction to the bus gives the impression that the bus is moving along the street.

I like a bit of variety and as one who is familiar with the ever changeable UK weather, it seemed apt to extend the capabilities further by adding buttons to change the weather conditions and times of day.

I also like to cut corners, so I downloaded this PrefixFree JavaScript file from GitHub and added it to the <head> of my HTML document to save writing CSS prefixes for every browser.

Ok, so how did I do this?

To create this animation I’ve used a combination of;

  1. HTML code
  2. CSS3 animation
  3. Spritesheet for the bus
  4. JavaScript/jQuery code to create the weather conditions and change backgrounds

In this blog post I’ll look at sections 1-3 above and explain how each was achieved. Part 2 of this blog post will deal with the JavaScript/jQuery implementation.

Back to top ^

1. HTML code

First of all, let’s look at the HTML code, and there is not much to it.

<div id="weather"></div>

<div class="foreground" id="fore">
  <ul class="busstops">
    <li id="stop_1">Sunny</li>
    <li id="stop_2">Rainy</li>
    <li id="stop_3">Sunset</li>
    <li id="stop_4">Night</li>
    <li id="stop_5">Snowy</li>
  <button id="buttonStop">Stop the bus</button>

<div class="midground" id="mid">
  <div class="bus"></div>

<div class="background" id="back"></div>

You can see that it’s pretty simple – I’ve basically created 4 layers, entitled;

  • Weather – this layer is where the jQuery weather conditions are loaded in.
  • Foreground – this layer contains a UL for the weather buttons as well as a button to “Stop the bus”, which stops the animation. (It is always good practise to provide web users with the option to stop and start animations).
  • Midground – this layer contains the bus and street scene
  • Background – this layer contains the background scenery

These layers are styled and arranged using CSS and z-index layers, which I will discuss further in the next section.

You can see there are no images included in the HTML code, these are all set as background images in the CSS.

Back to top ^

2. CSS3 animation

OK, so now we know what the HTML looks like, and it’s not that scary, let’s have a look at the CSS code. The basic premise is that I have created a scene by layering divs (blocks of content) using the z-index property. (If you are not familiar with the z-index, z-indexes allow you to set the stacking order of html elements. For more information see: W3Schools: z-index).

Lets start with the weather layer.


This layer is the container for the weather conditions, which are only applied when you select the “Rainy” or “Snowy” buttons at the top of the screen. This layer is positioned at z-index:4 which is the highest layer so this is always on top.

#weather {
  z-index: 4;


This layer is the container for the buttons and is positioned at z-index:4. This layer is static.

.foreground {
  z-index: 4;
  margin:0 auto;


This layer is positioned at z-index:3 so it appears under both the foreground and weather layers. Midground div layer contains the bus and street scene animation. Here’s the CSS for the street scene animation:


.midground {
  animation: parallax_mg linear 20s infinite;
  background: url(edinburgh_ground_normal.png) 0 100% repeat-x;
  z-index: 3;
@keyframes parallax_mg {
  0% { background-position: 3000px 100%;}
  100% {background-position: 0 100%; }


I’m sure most of this CSS looks pretty familiar to those of you who use it. I’ve added a background image (shown below) and set it to repeat it horizontally (repeat-x). The background image is 3000px wide:


It’s the animation: parallax_mg linear 20s infinite line that’s doing the work here, so let’s break it down:

  1. Animation’ is the CSS property, in the same way you would use color.
  2. parallax_mg’ is the animation name, I’ve written this shorthand but it can also be written as animation-name. This name can be anything you want.
  3. linear’ is the timing function of the animation. I’ve used ‘linear’ which means my animation moves with the same speed from start to end. Again, I’ve used shorthand, but written in full it’s animation-timing-function.
  4. 20s’ is the duration of the animation, in my case, I’ve specified it should take 20 seconds to run from start to finish. (animation-duration)
  5. infinite’ is the amount of times the animation should play (animation-iteraction-count), I’ve selected ‘infinite’ to play as a loop, but you can also specify a number if you only want the animation to run a few times.
  6. @keyframes parallax_mg – specifies the animation keyframes. I’m saying move the horizontal or x position of the background image from 3000px (which is the width of the image) to 0px. In other words, from right to left.

(More information on the animation property can be found at W3Schools CSS3 Animations ).

Ok, so if you’ve got this, then the same theory is applied to the background layer, the only difference is that I have used 3 background images rather than 1.


.background {
  background-repeat: repeat-x;
  background-position: 0 100%;
  z-index: 2;
  animation: parallax_bg linear 40s infinite;
  animation-play-state: running;

@keyframes parallax_bg {
  0% { background-position: 1800px 100%, 1600px 100%, 1200px 100%;}
  100% { background-position: 0 100%, 0 100%, 0 100%;}

I’ve set the trees layer as the top background image (1800px wide)

Then the hill… (1600px wide)
Followed by the Edinburgh skyline image (1200px wide)
You will notice that the background images are not all the same width, this is deliberate; the wider images have more of a distance to move in the animation, so they appear to animate faster. The smaller image of the skyline, which is the furthest away, will move more slowly. This technique is know as parallax scrolling: the background elements move more slowly than the foreground elements creating an illusion of depth. Father Ted viewers may remember him trying to explain a similar concept to Dougal.

You may also notice a new property: animation-play-state: running;

This is where you can specify if the animation is automatically ‘running‘, or ‘paused’ when the page loads. I have toggled this property with JavaScript in section 4.

The HTML layer

Behind all the images I have a static gradient background for the entire page. I have done this by adding a CSS gradient background to the HTML element.

html {
  height: 100% !important;
  background: rgba(0,176,245,1);
  background: -moz-linear-gradient(top, rgba(0,176,245,1) 0%, rgba(255,255,255,1) 100%);
  background: -webkit-gradient(left top, left bottom, color-stop(0%, rgba(0,176,245,1)), color-stop(100%, rgba(255,255,255,1)));
  background: -webkit-linear-gradient(top, rgba(0,176,245,1) 0%, rgba(255,255,255,1) 100%);
  background: -o-linear-gradient(top, rgba(0,176,245,1) 0%, rgba(255,255,255,1) 100%);
  background: -ms-linear-gradient(top, rgba(0,176,245,1) 0%, rgba(255,255,255,1) 100%);
  background: linear-gradient(to bottom, rgba(0,176,245,1) 0%, rgba(255,255,255,1) 100%);
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00b0f5', endColorstr='#ffffff', GradientType=0 );

Ok, I hope that makes sense, let’s now look at the bus.

Back to top ^

3. The bus spritesheet

I decided to try out creating a spritesheet within Adobe Flash for the bus. (For more information see this nice online video for an explanation of spritesheets). To do this I created a bus symbol in Flash and then animated the wheels using clockwise motion tweens on a timeline consisting of 16 frames.

I then selected the symbol from the Flash symbol library, (right-clicked) and selected “Generate Sprite Sheet”. I did have to fiddle around with the sprite sheet output options, but by selecting “Custom” for the image dimensions and then setting the output width to match the symbol width and the output height to 16 x the symbol height (= frame number x symbol height) worked for me. Flash provides you with a preview screen and if configured correctly you should see images of your symbol tiled vertically, 1 for each frame used. You can see a smaller version of my bus spritesheet below.
Bus spritesheet
Once the bus spritesheet was created I then used the following CSS to ‘play’ through the spritesheet.

.bus {
  animation: bus-cycle 1s steps(16) infinite;
  animation-play-state: running;
  background: url(animation_spritesheet_ltor.png) 0 0 no-repeat;
  height: 216px;
  width: 384px;
  position: absolute;
  bottom: 60px;
  left: 50%;
  margin-left: -200px;
  transform: translateZ(0); /* offers a bit of a performance boost by pushing some of this processing to the GPU in Safari*/

@keyframes bus-cycle {
  0% {background-position: 0 0; }
  100% {background-position: 0 -3472px; } /* Must be full height of sprite or skipping will happen.*/

The difference here is that I’ve used the animation-timing-property property ‘steps’ to cycle through the spritesheet in 16 steps from the top of the image to the bottom. Each step lasting 1 second each, the number of steps equalling the number of images in the spritesheet:

animation: bus-cycle 1s steps(16) infinite;

The width and height properties are set to exactly the same width and height of 1 bus in the spritesheet. I did have to tinker with the height settings to make sure this matched exactly 1/16 of the spritesheet. Being out by a few pixels resulted in a rather bumpy rendering of the bus rather than a smooth transition.

The background-position is set to move from 0px to -3472px, this is the full height of the spritesheet image.


So, if you’ve got this far and you’re still reading, well done, and thanks for staying with it. There are plenty more things I could do with CSS3 animation, and this blog post is only a very brief overview, but hopefully this will have given you some ideas to get started with.

In my next blog post I’ll look at Section 4: JavaScript/jQuery code for the weather generation.

Back to top ^

Useful links and references

Images from:

Brief history of Flash

Brief history of Flash

When I first started working in the web industry Macromedia Flash as it was known then, was considered one of the coolest things around. Macromedia Flash was a program where you could create rich interactive media content with shiny scalable vector graphics that looked the same in all browsers, (providing you had the plugin installed). This might not sound amazing, but this was in the late 1990s and the vastly different webpage rendering of Netscape Communicator and Internet Explorer 5, meant trying to get your website to look the same in both these browsers was a mammoth task; CSS was not supported well, and layout was controlled using tables and the infamous transparent spacer.gif. Flash was great; a flash object looked the same in all browsers, it could scale to fit the screen and the file size was tiny, handy when you were using that dial-up-modem to get online. All you had to do was download the flash plugin to play content in your browser.

Flash was so popular that it soon became the fashion for websites to have a full screen launch page, yep all 480 x 640 pixels of it. Who remembers visiting websites and being asked to choose between the “HTML” or “Flash” version, like who would want to visit the boring HTML version right, when you could experience the fun flash version with animations and games?

However, as web technologies developed Flash found it’s place as the tool of choice for banner ads, games, simulations and e-learning objects. All was good for the next decade or so, and then in 2007 Apple invented the iPhone, the iPad followed in 2010 and mobile and tablet browsing became THE thing. Apple would not allow Flash player on the iPhone and iPad, it made the devices unstable and took up too much processing memory. Due to the rising popularity of mobile and tablet browsing alternatives to Flash had to be sought. This leads me to the start of HTML5 as an alternative to Flash.

For more information please read: Wikipedia: Apple and Adobe Flash controversy

Back to top ^

WhatsApp Dick‽

BBC embrace WhatsApp as a legitimate news service

Launched on February 28th, the BBC have fully engaged with WhatsApp to deliver interactive content around the reburial of Richard III. Stewart Lamb Cromar reviews the quality, diversity and innovation of their instant messaging publications.

1) Fri 13 Mar

After 13 days of radio silence, the BBC published their first piece of interactive content. This BBC News article from September 2012 wasn’t the best of starts in terms of engagement or breaking new ground.

2) Sun 15 Mar

Another archival post from May 2014, this time accompanied with a photograph of Usain Bolt.

3) Mon 16 Mar

This interactive video map represents the first new 100% piece of Richard III content we’ve seen. Whilst the BBC claim this page is best viewed on their desktop site, I found the 8-part video perfectly usable on a mobile device. What I did find disconcerting was the lack of audio, it’s more a slideshow than video to be honest and it would have benefited from someone narrating the on-screen text.

4) Tue 17 Mar

Our third previously published news story (April 2014), this time about Sherlock actor Martin Freeman playing Shakespeare’s doomed king Richard III in the West End.

5) Wed 18 Mar

A second WhatsApp photograph asks us to reconsider our thinking on Richard III’s hair and eye colour.

6) Thu 19 Mar

Did you know Richard III has some deadly connections with both solar and lunar eclipses? #topical

7) Fri 20 Mar

Things start to lighten up, a fun little CBBC video and an emoji opinion poll:


8) Sat 21 Mar

Before King Richard III’s remains are reinterred during a ceremony next Thursday, we’re treated to 6 facts for the remaining 6 days. And finally, the emoji poll results are revealed:




With the reburial still left it may be a little premature to make any firm conclusions, but based on what we’ve been sent so far I’m pretty impressed. Despite a shaky start, I genuinely find it quite exciting to get a WhatsApp alert direct from the BBC. Their now daily Richard III messages are a perfect appetiser before engaging with extended Richard III BBC News website content.

With the sole exception of the emoji poll, communication for me was strictly one-way. This may be down to my lack of experience with WhatsApp, had I asked a question or commented on one their posts they may well have been answered.

As with Facebook and Twitter before it, it’s only a matter of time before other major content providers adopt WhatsApp as a serious educational delivery platform. I would love to hear about the success of their Richard III WhatsApp alert service when it concludes, in particular how many subscribers they garnered and what level of resourcing was required internally.

Did you also subscribe to this alert service? Please let me know your thoughts in the comments section below or via Twitter.

Related Links

Bringing life to the case study


“Case studies are an invaluable record of the clinical practices of a profession. While case studies cannot provide specific guidance for the management of successive patients, they are a record of clinical interactions, which help us to frame questions for more rigorously designed clinical studies. Case studies also provide valuable teaching material, demonstrating both classical and unusual presentations which may confront the practitioner.”
Dr. Brian Budgell, DC, Phd, JCCA

They’re also great fun to work on. Here at IC, my team work closely with the UoE’s School of Medicine and NHS Scotland to create online training modules for students, health care professionals, social care staff and carers. We also produce outward facing websites that provide help, advice and support for patients and families. For this blog post I thought I’d focus on a small but crucial component of the learning platforms we help create.

Case studies are developed with particular learning objectives in mind. They’re based on fictional individuals but depict real events that the user may experience in their career. One of our current projects, HEARTe provides health and social care staff with CPD training in the form of case studies. Each module is constructed and validated by a team of specialists, nurses, psychologists, GP’s and pharmacists with IC’s developers attending each meeting, documenting and converting the results into educational content. Case studies are intended to portray the type of every-day people we encounter in our lives, from taxi drivers and policemen to retirees and teachers. They have to both be layered in detail but not detract from the training materials we develop.


Once each case study has been thoroughly researched and constructed by the authors and project lead, the process of applying personality and layering detail can start. As case studies are fictional characters with real-life conditions affecting their lives and decisions, we use illustrations rather than photographs of real people. However, finding a subject to draw from multiple perspectives can be tricky. This is when we turn to Google Images and in particular, the image search results of celebrities.

From an Interactive Content Developer’s perspective,  the ‘celeb’ is a perfect source from which to base our case studies on. The variety of images on Google provide us with the ability to draw them from different angles whilst maintaining proportion and consistency throughout the entire module. If the case study has a relative in the module… let’s say for example, the Baldwins (who have an seemingly endless production-line of brothers!), we can use each brother for visual reference and create content suitable for hereditary conditions. Of course, we alter the features, hair colour, skin tone and clothing but underneath all the layers of case study-related-character, DVT sufferer Frank (the plumber) is actually Elliott Gould (the Hollywood actor). Once we have enough character detail in place, the case study comes to life, providing the user with all the crucial elements: age, gender, diet, fitness level, environment, personality and occupation.


All of our illustrations are created in vector-based software, providing us with the flexibility of scaling them to any size required. We also try to work within the software chosen for each project. For example, if we’re developing Flash-based content, we’ll create the images from within Flash’s toolset. If the platform requires responsive content, we’ll work with either Adobe Edge or Tumult Hype. I typically work with InDesign to create wireframes or illustrations. From there, I would import my visuals into Photoshop, resize, compress and export as a transparent background PNG, ready to be used for Hype.


When approaching the build of a character, skin tones and hair are applied first, followed by facial detail, eyes, teeth and finally clothing. Once we have a fully fleshed-out character, we can create their environments (animated vehicles, buildings or weather) and decide which scenes require character animation (breathing, walking, speaking or blinking). If the case study involves a hospital environment, we have to accurately depict medical equipment and instruments, some of which may function like their real-life counterparts.

All of these small components add to a rich and detailed case study, which in turn help the user quickly familiarise themselves with their virtual patient, ensuring every facet of their life and medical condition are not overlooked, whilst making the learning experience a more engaging and memorable experience.