Create An Animated Bar Graph With HTML, CSS And jQuery


People in boardrooms across the world love a good graph. They go nuts for PowerPoint, bullet points and phrases like “run it up the flagpole,” “blue-sky thinking” and “low-hanging fruit,” and everything is always “moving forward.” Backwards is not an option for people who facilitate paradigm shifts in the zeitgeist1. Graphs of financial projections, quarterly sales figures and market saturation are a middle-manager’s dream.


How can we as Web designers get in on all of this hot graph action? There are actually quite a few ways to display graphs on the Web. We could simply create an image and nail it to a Web page. But that’s not very accessible or interesting. We could use Flash, which is quite good for displaying graphs — but again, not very accessible. Besides, designers, developers and deities2 are falling out of love with Flash. Technologies such as HTML5 can do many of the same things without the need for a plug-in. The new HTML5 <canvas> element could even be adapted to the task. Plenty of charting tools are online that we might use. But what if we wanted something a little more tailored?

There are pros and cons to the wide range of resources available to us, but this tutorial will not explore them all. Instead, we’ll create our graph using a progressively enhanced3 sprinkling of CSS3 and jQuery. Because we can.

What Are We Making?

We’re making this4. And more! Here are some possibilities on how you can extend the techniques explored in this tutorial:

  • A progress bar that indicates how long until the end of all humanity in the event of a zombie plague;
  • A graph indicating the decline in safe outdoor activities during a zombie plague;
  • A frighteningly similar graph indicating the decline in manners during a zombie plague;
  • The increase of people who were unaware of the zombie plague because they were sharing with all of their now-deceased friends on Facebook what they did on FarmVille5.

Or you could create a graph or quota bar that simply illustrates something useful and less full of dread and zombies. So, let’s get on with it.

What You’ll Need

  • A text or HTML editor. Take your pick6; many are out there.
  • jQuery7. Practice safe scripting and get the latest one. Keep the jQuery website open so that you can look up the documentation as you go.
  • Possibly an image editor, such as Paint8, to mock up what your graph might look like.
  • A modern and decent Web browser to preview changes.

That should do it. Please note that this tutorial is not designed as an introduction to either HTML, CSS, jQuery or zombies. Some intermediate knowledge of these three technologies and the undead is assumed.

The Mark-Up

You can create the underlying HTML for a graph in a number of ways. In this tutorial, we’ll start with a table, because it will make the most sense visually if JavaScript or CSS is not applied. That’s a big checkmark in the column for accessibility.

Quick! You’ve just been given some alarming figures. The population of tanned zombies is projected to spiral out of control in the next few years. The carbon tigers and blue monkeys are under immediate threat. Then the tanned zombies will probably come for us. But you’re just a designer. What could you possibly do to help?

I know! You could make a Web page that illustrates our imminent demise with nice, calming, smoothly animated graphics!

To begin, let’s put this data into a table, with columns for each year, and rows for the different species.

<!doctype html>
<html lang="en">
      <meta charset="utf-8">
      <meta name="viewport" content="width=1024">
      <title>Example 01: No CSS</title>

      <div id="wrapper">
         <div class="chart">
            <h3>Population of endangered species from 2012 to 2016</h3>
            <table id="data-table" border="1" cellpadding="10" cellspacing="0"
            summary="The effects of the zombie outbreak on the populations
            of endangered species from 2012 to 2016">
               <caption>Population in thousands</caption>
                     <th scope="col">2012</th>
                     <th scope="col">2013</th>
                     <th scope="col">2014</th>
                     <th scope="col">2015</th>
                     <th scope="col">2016</th>
                     <th scope="row">Carbon Tiger</th>
                     <th scope="row">Blue Monkey</th>
                     <th scope="row">Tanned Zombie</th>

View the example below to see how it looks naked, with no CSS or JavaScript applied. The accessibility of this table will enable people using screen readers to understand the data and the underlying message, which is “Run for your life! The zombies are coming!”


The easy part is now out of the way. Now, let’s tap into the power of CSS and JavasScript (via jQuery) to really illustrate what the numbers are telling us. Technically, our aim is to create a graph that works in all modern browsers, from IE 8 on.

Did I say all modern browsers? IE 8 is lucky: it gets to hang out with the cool kids. Browsers that support CSS3 will get a few extra sprinkles.

“By Your Powers Combined…”

If you wish to summon Captain Planet10, you may11 have12 to13 look14 elsewhere15. If you want to learn how to combine CSS and jQuery to create a graph that illustrates our impending doom at the hands of a growing army of zombies who prefer bronzer over brains, then read on.

The first thing to do is style our table with some basic CSS. This is a nice safety net for people who haven’t enabled JavaScript in their browser.


Getting Started In jQuery

We’ll use jQuery to create our graph on the fly, separate from the original data table. To do this, we need to get the data out of the table and store it in a more usable format. Then, we can add to our document new elements that use this data in order to construct our graph.

Let’s get started by creating our main createGraph() function. I’ve abbreviated some of the inner workings of this function so that you get a clearer picture of the structure. Don’t forget: you can always refer to the source code that comes with this tutorial.

Here’s our basic structure:

// Wait for the DOM to load everything, just to be safe
$(document).ready(function() {

   // Create our graph from the data table and specify a container to put the graph in
   createGraph('#data-table', '.chart');

   // Here be graphs
   function createGraph(data, container) {
      // Declare some common variables and container elements

      // Create the table data object
      var tableData = {

      // Useful variables to access table data

      // Construct the graph

      // Set the individual heights of bars
      function displayGraph(bars) {

      // Reset the graph's settings and prepare for display
      function resetGraph() {

      // Helper functions

      // Finally, display the graph via reset function

We pass two parameters to this function:

  1. The data, in the form of a table element;
  2. A container element, where we’d like to place our graph in the document.

Next up, we’ll declare some variables to manage our data and container elements, plus some timer variables for animation. Here’s the code:

// Declare some common variables and container elements
var bars = [];
var figureContainer = $('<div id="figure"></div>');
var graphContainer = $('<div class="graph"></div>');
var barContainer = $('<div class="bars"></div>');
var data = $(data);
var container = $(container);
var chartData;
var chartYMax;
var columnGroups;

// Timer variables
var barTimer;
var graphTimer;

Nothing too exciting here, but these will be very useful later.

Getting The Data

Besides simply displaying the data, a good bar chart should have a nice big title, clearly labelled axes and a color-coded legend. We’ll need to strip the data out of the table and format it in a way that is more meaningful in a graph. To do that, we’ll create a JavaScript object that stores our data in handy little functions. Let’s give birth to our tableData{} object:

// Create table data object
var tableData = {
   // Get numerical data from table cells
   chartData: function() {
   // Get heading data from table caption
   chartHeading: function() {
   // Get legend data from table body
   chartLegend: function() {
   // Get highest value for y-axis scale
   chartYMax: function() {
   // Get y-axis data from table cells
   yLegend: function() {
   // Get x-axis data from table header
   xLegend: function() {
   // Sort data into groups based on number of columns
   columnGroups: function() {

We have several functions here, and they are explained in the code’s comments. Most of them are quite similar, so we don’t need to go through each one. Instead, let’s pick apart one of them, columnGroups:

// Sort data into groups based on number of columns
columnGroups: function() {
   var columnGroups = [];
   // Get number of columns from first row of table body
   var columns = data.find('tbody tr:eq(0) td').length;
   for (var i = 0; i < columns; i++) {
      columnGroups[i] = [];
      data.find('tbody tr').each(function() {
   return columnGroups;

Here’s how it breaks down:

  • Create the columnGroups[] array to store the data;
  • Get the number of columns by counting the table cells (td) in the first row;
  • For each column, find the number of rows in the table body (tbody), and create another array to store the table cell data;
  • Then loop through each row and grab the data from each table cell (via the jQuery text() function), and then add it to the table cell data array.

Once our object is full of juicy data, we can start creating the elements that make up our graph.

Using The Data

Using the jQuery $.each function, we can now loop through our data at any point and create the elements that make up our graph. One of the trickier bits involves inserting the bars that represent each species inside the yearly columns.

Here’s the code:

// Loop through column groups, adding bars as we go
$.each(columnGroups, function(i) {
   // Create bar group container
   var barGroup = $('<div class="bar-group"></div>');
   // Add bars inside each column
   for (var j = 0, k = columnGroups[i].length; j < k; j++) {
      // Create bar object to store properties (label, height, code, etc.) and add it to array
      // Set the height later in displayGraph() to allow for left-to-right sequential display
      var barObj = {};
      barObj.label = this[j];
      barObj.height = Math.floor(barObj.label / chartYMax * 100) + '%'; = $('<div class="bar fig' + j + '"><span>' + barObj.label + '</span></div>')
   // Add bar groups to graph

Excluding the headings, our table has five columns with three rows. For our graph, this means that for each column we create, three bars will appear in that column. The following image shows how our graph will be constructed:


Breaking it down:

  • For each column, create a container div;
  • Loop inside each column to get the row and cell data;
  • Create a bar object (barObj{}) to store the properties for each bar, such as its label, height and mark-up;
  • Add the mark-up property to the column, applying a CSS class of '.fig' + j to color code each bar in the column, wrapping the label in a span;
  • Add the object to our bars[] array so that we can access the data later;
  • Piece it all together by adding the columns to a container element.

Bonus points if you noticed that we didn’t set the height of the bars. This is so that we have more control later on over how the bars are displayed.

Now that we have our bars, let’s work on labelling our graph. Because the code to display the labels is quite similar, talking you through all of it won’t be necessary. Here’s how we display the y-axis:

// Add y-axis to graph
var yLegend   = tableData.yLegend();
var yAxisList   = $('<ul class="y-axis"></ul>');
$.each(yLegend, function(i) {
   var listItem = $('<li><span>' + this + '</span></li>')

This breaks down as follows:

  • Get the relevant table data for our labels,
  • Create an unordered list (ul) to contain our list items;
  • Loop through the label data, and create a list item (li) for each label, wrapping each label in a span;
  • Attach the list item to our list;
  • Finally, attach the list to a container element.

By repeating this technique, we can add the legend, x-axis labels and headings for our graph.

Before we can display our graph, we need to make sure that everything we’ve done is added to our container element.

// Add bars to graph

// Add graph to graph container

// Add graph container to main container

Displaying The Data

All that’s left to do in jQuery is set the height of each bar. This is where our earlier work, storing the height property in a bar object, will come in handy.

We’re going to animate our graph sequentially, one by one, uno por uno.

One possible solution is to use a callback function to animate the next bar when the last animation is complete. However, the graph would take too long to animate. Instead, our graph will use a timer function to display each bar after a certain amount of time, regardless of how long each bar takes to grow. Rad!

Here’s the displayGraph() function:

// Set the individual height of bars
function displayGraph(bars, i) {
   // Changed the way we loop because of issues with $.each not resetting properly
   if (i < bars.length) {
      // Animate the height using the jQuery animate() function
         height: bars[i].height
      }, 800);
      // Wait the specified time, then run the displayGraph() function again for the next bar
      barTimer = setTimeout(function() {
         displayGraph(bars, i);
      }, 100);

What’s that you say? “Why aren’t you using the $.each function like you have everywhere else?” Good question. First, let’s discuss what the displayGraph() function does, then why it is the way it is.

The displayGraph() function accepts two parameters:

  1. The bars to loop through,
  2. An index (i) from which to start iterating (starting at 0).

Let’s break down the rest:

  • If the value of i is less than the number of bars, then keep going;
  • Get the current bar from the array using the value of i;
  • Animate the height property (calculated as a percentage and stored in bars[i].height);
  • Wait 100 milliseconds;
  • Increment i by 1 and repeat the process for the next bar.

“So, why wouldn’t you just use the $.each function with a delay() before the animation?”

You could, and it would work just fine… the first time. But if you tried to reset the animation via the “Reset graph” button, then the timing events wouldn’t clear properly and the bars would animate out of sequence.

I would like to be proven wrong, and if there is a better way to do this, feel free to sound off in the comments section.

Moving on, here’s resetGraph():

// Reset graph settings and prepare for display
function resetGraph() {
   // Stop all animations and set the bar's height to 0
   $.each(bars, function(i) {
      $(bars[i].bar).stop().css('height', 0);

   // Clear timers

   // Restart timer
   graphTimer = setTimeout(function() {
      displayGraph(bars, 0);
   }, 200);

Let’s break resetGraph() down:

  • Stop all animations, and set the height of each bar back to 0;
  • Clear out the timers so that there are no stray animations;
  • Wait 200 milliseconds;
  • Call displayGraph() to animate the first bar (at index 0).

Finally, call resetGraph() at the bottom of createGraph(), and watch the magic happen as we bask in the glory of our hard work.

Not so fast, sunshine! Before we go any further, we need to put some clothes on.


The first thing we need to do is hide the original data table. We could do this in a number of ways, but because our CSS will load well before the JavaScript, let’s do this in the easiest way possible:

#data-table {
   display: none;

Done. Let’s create a nice container area to put our graph in. Because a few unordered lists are being used to make our graph, we’ll also reset the styles for those. Giving the #figure and .graph elements a position: relative is important because it will anchor the place elements exactly where we want in those containers.

/* Containers */

#wrapper {
   height: 420px;
   left: 50%;
   margin: -210px 0 0 -270px;
   position: absolute;
   top: 50%;
   width: 540px;

#figure {
   height: 380px;
   position: relative;

#figure ul {
   list-style: none;
   margin: 0;
   padding: 0;

.graph {
   height: 283px;
   position: relative;

Now for the legend. We position the legend right down to the bottom of its container (#figure) and line up the items horizontally:

/* Legend */

.legend {
   background: #f0f0f0;
   border-radius: 4px;
   bottom: 0;
   position: absolute;
   text-align: left;
   width: 100%;

.legend li {
   display: block;
   float: left;
   height: 20px;
   margin: 0;
   padding: 10px 30px;
   width: 120px;

.legend span.icon {
   background-position: 50% 0;
   border-radius: 2px;
   display: block;
   float: left;
   height: 16px;
   margin: 2px 10px 0 0;
   width: 16px;

The x-axis is very similar to the legend. We line up the elements horizontally and anchor them to the bottom of its container (.graph):

/* x-axis */

.x-axis {
   bottom: 0;
   color: #555;
   position: absolute;
   text-align: center;
   width: 100%;

.x-axis li {
   float: left;
   margin: 0 15px;
   padding: 5px 0;
   width: 76px;

The y-axis is a little more involved and requires a couple of tricks. We give it a position: absolute to break it out of the normal flow of content, but anchored to its container. We stretch out each li to the full width of the graph and add a border across the top. This will give us some nice horizontal lines in the background.

Using the power of negative margins, we can offset the numerical labels inside the span so that they shift up and to the left. Lovely!

/* y-axis */

.y-axis {
   color: #555;
   position: absolute;
   text-align: right;
   width: 100%;

.y-axis li {
   border-top: 1px solid #ccc;
   display: block;
   height: 62px;
   width: 100%;

.y-axis li span {
   display: block;
   margin: -10px 0 0 -60px;
   padding: 0 10px;
   width: 40px;

Now for the meat in our endangered species sandwich: the bars themselves. Let’s start with the container element for the bars and the columns:

/* Graph bars */

.bars {
   height: 253px;
   position: absolute;
   width: 100%;
   z-index: 10;

.bar-group {
   float: left;
   height: 100%;
   margin: 0 15px;
   position: relative;
   width: 76px;

Nothing too complicated here. We’re simply setting some dimensions for the container, and setting a z-index to make sure it appears in front of the y-axis markings.

Now for each individual .bar:

.bar {
   border-radius: 3px 3px 0 0;
   bottom: 0;
   cursor: pointer;
   height: 0;
   position: absolute;
   text-align: center;
   width: 24px;

.bar.fig0 {
   left: 0;

.bar.fig1 {
   left: 26px;

.bar.fig2 {
   left: 52px;

The main styles to note here are:

  • position: absolute and bottom: 0, which means that the bars will be attached to the bottom of our graph and grow up;
  • the bar for each species (.fig0, .fig1 and .fig2), which will be positioned within .bar-group.

Now, why don’t we minimize the number of sharp edges on any given page by using the border-radius property to round the edges of the top-left and top-right corners of each bar? OK, so border-radius isn’t really necessary, but it adds a nice touch for browsers that support it. Thankfully, the latest versions of the most popular browsers do support it.

Because we’ve placed the values from each table cell in each bar, we can add a neat little pop-up that appears when you hover over a bar:

.bar span {
   #fefefe url(../images/info-bg.gif) 0 100% repeat-x;
   border-radius: 3px;
   left: -8px;
   display: none;
   margin: 0;
   position: relative;
   text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;
   width: 40px;
   z-index: 20;

   -webkit-box-shadow: rgba(0, 0, 0, 0.6) 0 1px 4px;
   box-shadow: rgba(0, 0, 0, 0.6) 0 1px 4px;

.bar:hover span {
   display: block;
   margin-top: -25px;

First, the pop-up is hidden from view via display: none. Then, when a .bar element is hovered over, we’ve set display: block to bring it into view, and set a negative margin-top to make it appear above each bar.

The text-shadow, rgba and box-shadow properties are currently supported by most modern browsers as is. Of these modern browsers, only Safari requires a vendor prefix (-webkit-) to make box-shadow work. Note that these properties are simply enhancements to our graph and aren’t required to understand it. Our baseline of Internet Explorer 8 simply ignores them.

Our final step in bringing everything together is to color code each bar:

.fig0 {
   background: #747474 url(../images/bar-01-bg.gif) 0 0 repeat-y;

.fig1 {
   background: #65c2e8 url(../images/bar-02-bg.gif) 0 0 repeat-y;

.fig2 {
   background: #eea151 url(../images/bar-03-bg.gif) 0 0 repeat-y;

In this example, I’ve simply added a background-color and a background-image that tiles vertically. This will update the styles for the bars and the little icons that represent them in the legend. Nice.

And, believe it or not, that is it!

The Finished Product


That about wraps it up. I hope we’ve done enough to alert the public to the dangers of zombie over-population. More than that, however, I hope you’ve gained something useful from this tutorial and that you’ll continue to push the boundaries of what can be done in the browser — especially with proper Web standards and without the use of third-party plug-ins. If you’ve got ideas on how to extend or improve anything you’ve seen here, don’t hesitate to leave a comment below, or find me on Twitter @derek_mack18.

Bonus: Unleashing The Power Of CSS3

This bonus is not as detailed as our main example. It serves mainly as a showcase of some features being considered in the CSS3 specification.

Because support for CSS3 properties is currently limited, so is their use. Although some of the features mentioned here are making their way into other Web browsers, Webkit-based ones such as Apple Safari and Google Chrome are leading the way.

We can actually create our graph using no images at all, and even animate the bars using CSS instead of jQuery.

Let’s start by removing the background images from our bars, replacing them with the -webkit-gradient property:

.fig0 {
   background: -webkit-gradient(linear, left top, right top, color-stop(0.0, #747474), color-stop(0.49, #676767), color-stop(0.5, #505050), color-stop(1.0, #414141));

.fig1 {
   background: -webkit-gradient(linear, left top, right top, color-stop(0.0, #65c2e8), color-stop(0.49, #55b3e1), color-stop(0.5, #3ba6dc), color-stop(1.0, #2794d4));

.fig2 {
   background: -webkit-gradient(linear, left top, right top, color-stop(0.0, #eea151), color-stop(0.49, #ea8f44), color-stop(0.5, #e67e28), color-stop(1.0, #e06818));

We can do the same with our little number pop-ups:

.bar span {
   background: -webkit-gradient(linear, left top, left bottom, color-stop(0.0, #fff), color-stop(1.0, #e5e5e5));

For more information on Webkit gradients, check out the Surfin’ Safari19 blog.

Continuing with the pop-ups, let’s introduce -webkit-transition. CSS transitions are remarkably easy to use and understand. When the browser detects a change in an element’s property (height, width, color, opacity, etc.), it will transition to the new property.

Again, refer to Surfin’ Safari20 for more information on -webkit-transition and CSS3 animation.

Here’s an example:

.bar span {
   background: -webkit-gradient(linear, left top, left bottom, color-stop(0.0, #fff), color-stop(1.0, #e5e5e5));
   display: block;
   opacity: 0;

   -webkit-transition: all 0.2s ease-out;

.bar:hover span {
   opacity: 1;

When you hover over the bar, the margin and opacity of the pop-up will change. This triggers a transition event according to the properties we have set. Very cool.

Thanks to -webkit-transition, we can simplify our JavaScript functions a bit:

// Set individual height of bars
function displayGraph(bars, i) {
   // Changed the way we loop because of issues with $.each not resetting properly
   if (i < bars.length) {
      // Add transition properties and set height via CSS
      $(bars[i].bar).css({'height': bars[i].height, '-webkit-transition': 'all 0.8s ease-out'});
      // Wait the specified time, then run the displayGraph() function again for the next bar
      barTimer = setTimeout(function() {
         displayGraph(bars, i);
      }, 100);
// Reset graph settings and prepare for display
function resetGraph() {
   // Set bar height to 0 and clear all transitions
   $.each(bars, function(i) {
      $(bars[i].bar).stop().css({'height': 0, '-webkit-transition': 'none'});

   // Clear timers

   // Restart timer
   graphTimer = setTimeout(function() {
      displayGraph(bars, 0);
   }, 200);

Here are the main things we’ve changed:

  • Set the height of the bars via the jQuery css() function, and allowed CSS transitions to take care of the animation;
  • When resetting the graph, turned transitions off so that the height of the bars is instantly set to 0.

Check out the example21 if you have the latest version of Safari or Chrome installed.

Ultra-Mega Webkit Bonus: Now In 3-D!

For a sneak peek of what the future holds, check out a little experiment22 that I put together, with a 3-D effect and CSS transforms. Again, it requires the latest versions of Safari or Chrome:

As in our previous Webkit example, there are no images, and all animation is handled via CSS. Kiss my face!23

I can’t tell you what to do with all this information. But I do caution you about the potential misuse of your new powers. In the words of our friend Captain Planet, “The power is yours!”

Use it wisely.

(al) (kw) (il)


  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23

↑ Back to topShare on Twitter

Derek Mack is a designer from Melbourne, Australia. He is one half of The Graphic Order, designers of Verbs IM for iOS and the award-winning Aussie Rules Live for iOS and Android.

  1. 1

    Great article and a beautiful result. Thanks Derek.

  2. 2

    Thanx for providing us with this useful inforamtion…really a nice post! I regularly read all of the posts here on Smashing Magazine.. and in all posts you surely give some extra effort…! :-)

  3. 3

    Wow, a very cool tutorial! Thanks for sharing!

  4. 4

    Adeniyi Moses Adetola

    September 23, 2011 4:11 am

    Excellent! Could easily be modified to fit ones needs.

  5. 5

    Just what I need! Thanks!

  6. 6

    Wow, that webkit experiment is awesome! Nice article Derek

  7. 7

    Saved to instapaper so I can never lose this post! :-)

  8. 8

    Excellent use of jQuery. I love when I see great tutorials utilizing jQuery’s potentials.
    As Adeniyi said, this can definitely be tailored for individual needs- well done!
    A nice addition might be to either use a tooltip plugin or utilize some CSS3 to stylize the popup. Great post!

  9. 10

    This is.. stimulating to say the least. The 3D animation is flawless. I’m going to work with this. I’m going to work with this a LOT. Thanks! Brilliant article!

  10. 11

    Đurica Bogosavljev

    September 23, 2011 5:02 am

    Wow!!! Great tutorial, very useful, thanks for sharing. Showing great potential of CSS3!

  11. 12

    Awesome Bar :)

  12. 13

    Justin St. Germain

    September 23, 2011 5:52 am

    very cool and will be great in the future, but, this doesnt work in IE or even in FF. to bad.

  13. 14

    it’s good for me~thanks~

  14. 15

    Great tut keep em coming

  15. 16

    Is there an easy way to switch this to a horizontal bar graph?

  16. 17

    Cracking article, and loving the Alan Partridge link!

  17. 18

    Great article! For super easy and great looking graphs/charts, I recommend looking into HighCharts. They have a ton of documentation and examples.

  18. 19

    Html5? CSS3? I’m sick of it! It’s too much for me!
    Do you have to write almost every post about it? I know it’s fresh and fun, but still it’s a new thing not a standard.

    • 20

      Yes, please Smashing Magazine.


      • 21

        Justin St. Germain

        September 26, 2011 1:12 pm

        now thats funny. thanks for the laugh. on that note, why the heck even use tables? we should just put all content in one large run on sentence that never seems to end and no images at all in the site with black page background and white text oh and use some blinking red text somewhere cause it is really eye catching. oops, was that a run on? :P

      • 22

        Why someone would even bother to design for a browser with ~2% usage.
        Pointless, time/cash consuming and unpleasant experience.
        I’ve never even used an IE 6 for something more than downloading FireFox since I got my first PC 7 years ago.
        You should educate your clients and make them change their browsers.
        When someone wants to force me to optimize the source code for IE 6 and don’t want to be educated, then I say “bye bye”, to them.

  19. 23

    Fantastic. Nice work on this.

  20. 24

    Flippin’ awesome!

  21. 25


    You’re humor through this was fantastic! As a fairly new developer your documents through the Javascript was much appreciated, you made this very to understand, and highly adaptable.

    I hope your joking, the only HTML5 found in this code is the doctype, everything else is HTML4. Also why not use CSS3? Being a great developer is about adapting to the ever changing world of technology. Plus using CSS3 gradients compared to an image means faster load times. See smashings article on this:


    unfortunately at my work I’m forced to use IE7 :( and the graph works perfectly in it. That is odd it isn’t working for you.

    • 26

      Forced to use IE7?

      Lucky u! I need to focus on cross-browser usability in a way that our websites are fully functional, even in IE6! XD But we will use as much CSS3 as we can while building ;)

  22. 27

    Man, JavaScript is a horrible mess. Such a shame.

  23. 28

    Or you could just use the Google Chart Tools API – ; but good tutorial nonetheless!

  24. 29

    Thanks for your kindness , but it’s not work in IE (i’m use ie7)

  25. 30

    Nice article – really informative!

  26. 31

    You shouldn’t over-hype webkit until the last bit. I’ve modified example 4 so it can now work with Firefox, Opera, Webkit and IE9.

    Also Firefox partially supports 3D, and Webkit do not fully support it so let’s not over-hype for God’s sake.

    • 32

      Awesome work!

      I was curious why Example 4 didn’t also support FF as I’ve been using those transitions in FF for quite some time.

      I should note I run FF nightly build 9.0a

    • 33

      Hi Tacklr, can you send me the code for supporting the graph in firefox, opera, Webkit and IE9.?

  27. 34

    This is cool stuff. And fun to read. Most important IMHO is the fact that this kind of data visualization is ALL ACCESSILBLE. Thank you Derek, this is the way to go.

  28. 35

    Be nice to see this for pie charts and some other forms of graphs as well. Thanks for a really cool tutorial.

  29. 36

    helpful article………………..i think you will like my work



  30. 37

    Great work done now its a request to blog owner that write an article about my site which is and publish it to your blog, thx for that act regards

  31. 38

    Bharat @ Online Tips

    September 25, 2011 8:58 am

    Very nicely and clearly explained…like this tutorial…

  32. 39

    Thanks…very intuitive section, would give a try! I’ve been using Google Chart awhile.

  33. 40
  34. 41

    Great article, but i think making ur own charting library seems a tad wasteful (of time). There’s a few solutions out there for jquery, some good (highcharts) some bad (jqplot).

  35. 42

    Evelyn J. Parham

    September 25, 2011 6:49 pm

    Great and nice article! Very intuitive section, would give a try! like this tutorial anyway! thanks for letting us to learn about this :) .

    i invite you to be visit my site

  36. 43

    Oh, what an amazing creation this is. I wish may IE 6, 7, 8 die so that we could use these kind of amazing stuff without any hesitation. thanks a lot for being so generous to share this!

  37. 44

    Great article. The explanation on _how_ this is achieved proves far more useful than any generic plugin could.

  38. 45

    Love it!

  39. 46

    Fantastic article…thanks

  40. 47

    daniel maffioletti

    September 26, 2011 8:20 am

    congratulation. very easy

  41. 48

    Very nice, thank you for that article. Great!

  42. 49

    Hi great article – great finished product.

    My only query is that you talk about providing a CSS layout for people with javascript disabled but if I read correct later on you then set the table to display:none which means that CSS will be read regardless of JS status so it’s not going to be viewable in none JS enabled browsers; I have just disabled JS in firefox and the data does indeed vanish.

    Perhaps the table should be hidden via Javascript – I understand that there will be a flicker as it turns off but if the page is lightweight then that shouldn’t be too great an incident and importantly you’d receive the graceful degradation that’s required.

    Great effect though in a JS browser

  43. 50

    Nice stuff Derek. You covered everything from the ground up.

    css transforms on webkit look amazing.

  44. 51

    beautiful and logical design tutorial … well done

  45. 52

    Derek is crazy, I was laughing all the time with the comments like “Not so fast, sunshine! Before we go any further, we need to put some clothes on.”… Great article, now lets use graphs everywhere, Saying how many coffees we drink everyday, or how many hours we sleep every night…

  46. 53

    Great article…. I will definitely try this

  47. 54

    Awesome! The 3D graph is really impressive!

  48. 55

    wooooooooow i really like it

  49. 56

    Thank you for taking the time to write this in such detail. I will certainly use techniques in future website design projects.

  50. 57


    Just want to repeat what Tacklr said:

    all parts of this demo can quite easily be made to work also in FF, except the 3D bit.

    (FF demo made by Tacklr, not me)

  51. 58

    Great article! The only question I have is, how would we go about displaying a “negative” bar? Basically if we wanted to display the bar on a financial site that has a negative return on investments? Anyone? Thanks in advance.

  52. 61

    Would anyone be kind enough to show how to make it so that the bars can be sorted, say from lowest to highest or the reverse? Thanks!

  53. 62

    Excellent tutorial. I’m trying to display the bars horizontally. Could anyone give me some hints? thx!

  54. 63

    awesome it is.. thanks. gr8 work mate.

  55. 64

    Very cool tutorial.

  56. 65

    Derek, I like this tutorial but I’m new to javascript (and basically web development in general). You made a comment in the tutorial that we can get the source code, but the only source I see are the lines embedded in the tutorial. That’s probably enough for most people but for a newbie like myself it would really be helpful to see the entire source code. Is it available somewhere on this page and I’m just missing it? Thanks for the help.

  57. 66

    What happened to the downloadable source files that used to be available?

  58. 67

    IT’S TOTALY AMAZING !!! Good work

    • 68

      Posted on Its just wuerndfol to see how three best friends wind up in a storythats just so complicated and poetic. I was amazed by the outcome ofevery situation and I think there should be more movies like this one.Even the music was perfect for the movie. I also really like it whenthe makers put something useful to know in the movie and in this one,they certainly did, but what I liked most is that the piece that themouse (or rat) played in the story, without it, the movie would havebeen less meaningful and I think its really great that people can comeup with these things to put in their movie which completes it without it, the film wouldnt have been the same. great piece ofwork

  59. 69

    Hi Derek Mack,

    This tutorial is awesome, can I have the complete source code of that?

  60. 70

    This is a great tutorial. Would anyone be able to help me to get 2 or more graphs on the 1 page each from a different table? Thanks for your help.

    • 71

      Hans – Easy peasey! Simply add the following to your page:

      <div class="chart2"… <table id="data-table2" etc…

      and the following to your CSS file:
      #data-table, #data-table2 {
      display: none;

      and the following to your .js file (after the initial createGraph call):
      createGraph('#data-table2', '.chart2');

  61. 72

    what javascript to i add so that the graph will show a label on the y axis? or show a $ sign for the values i am using on the y axis?

  62. 73

    Just curious now… How could I add a “selected” class to compare the current table/td information against whatever my users may have entered in a choice? My tables are built in MVC3, and I would like to highlight whichever td represented my user’s selection… any thoughts?

  63. 74

    Hello! I have two questions:

    1) Is it possible to denominate numbers, such as $101,700,000 as being $101.7 in both the y-axis and each bar graph? When I add a dollar symbol ($) the .js ceases to function.

    2) Is it possible to have each bar graph label display something different than what is being used to calculate it?


  64. 75

    Have you ever even tried to create your own CSS graph? If you have, you will know how hard it is. Using Flash is one way to go, but you just can’t beat a beautifully crafted CSS Graph. Have a look at these tutorials and techniques.

  65. 76

    Hey guys, i’m having a big problem with this because the graph doesn’t work on IE8 or IE9

    • 77

      .. okay i managed to solve the problem on the css. but now there is no transition: the “bars” just appears (no animation)

  66. 78

    Doe anyone know how I can modify this chart so there are only 4 bars instead of 5?
    Great tutorial, great chart, and a terrific learning tool. Thanks Derek.

  67. 79

    Thanks for the information.Really good work!!

  68. 80

    Good work Derek … its a great example of css & jquery. I am a newbie , thanks for demonstrating it. I tried to link all the pieces of the given code but its not working . Could you please upload the entire sourcecode.

    Thanks !

  69. 81

    Here is a jQuery plugin for doing the same and more:

  70. 82

    Genial! Awesome Derek, it’s exactly the kick start that I looked for.

  71. 83

    love the sarcasm about business lingo at the start, and the captain planet reference did bring back memories :) great tutorial on the whole. wanted to suggest that this can be done more easily using a charting tool. something like

  72. 84

    Thanks for the post. It is what I looking for. But I am newbie in jquery. Would you post it as downloadable pls!!!

  73. 85

    Thanks for the tutorial! These look and work great.
    I want to use these graphs further down on pages throughout my site. How can the script be modified to animate only once it is in view?

  74. 86


    I used the method provided in your article and produced several graph, vertical and horizontal bars. Now I run into a problem. I want to have a function to print the web page into PDF. If i just use the web browser printer in google chrome to save to PDF, the bars will be lost, while all those y-axis and x-axis, the lines will be displayed. so only the jquery animated graph cannot be printed. wonder if you or anyone on this site has an insight into this?

    Thanks for any help!

  75. 87

    Can anyone help me out with creating a version without grouping the columns? I’m just looking for a straightforward bar graph with one column per x-axis item. I’d do it myself, but my JS skills are seriously lacking.

    Love the look of these graphs, BTW. Excellent work!

  76. 89

    Awsome work!
    Can anyone share the complete set of code files with me?

  77. 90

    Steven Hughes

    May 7, 2013 7:54 am


    I’ve just created a mootools port of this script, I wondered whether a credit in the code is required and who this credit should be given to.


  78. 91

    Great, i like it.

  79. 92

    your graph is super awesome!
    I created a loan / credit calculator using Formidable form in wordpress and would love to use the results of the form to spit out a graph like yours.
    Any pointers? any one done something similar?

    Many thanks

  80. 93

    I’m aware that this is quite an old post, but I am hoping people still visit this page :)

    I absolutely love the look and animation of this graph, but have been struggling to turn it into a “Stacked” graph.

    Would anyone (Even the author, if I were to be so lucky) help me modify this into a stacked bar graph?

    Thanks so much!

    • 94

      Hi Michael,

      A stacked graph would mean you’d need to get the total number of tigers, monkeys and zombies for that year, and then find the year which had the highest total (in this case, it would be 2013 with 14,880). That would be your maximum (so round-up to 15,000 or 16,000 for the y-axis). You’d then use the total for each year to create a container element with a height corresponding to that total. The populations of each species could then be represented as percentages of that total, and you could offset the y-position by the height of the previous element. As a quick example, given a maximum of 16,000 (at a height of 253px), the population of 2013 would be 92.5%. Then you break down each population for for year as a percentage, setting it’s height at that value. You’d have to calculate the height of the previous element (as a pixel or percentage value) to stack the bars vertically, either via the top or margin-top properties.


  81. 95

    Veramente, veramente bello!

  82. 96

    Thank you so much! This is just what I’ve been looking for to use on my site.

  83. 97

    Did anyone of you commentators actually follow the tutorial *step by step* or you just wrote speaking bubbles?

    I followed the tutorial until the end of the jQuery/javascript section and it is absolutely UNCLEAR how to proceed. For instance, where do I have to insert the sections *Loop through column groups, adding bars as we go* and *Add y-axis to graph*, and what should I write inside the sections *Useful variables to access table data*, *Contruct the graph*, *Set the individual heights of bars* and *Helper functions*?

    You guys are gonna be kidding me. I like the style of writing and the final result is super pretty. But as tutorial is frankly very confusing. And frustrating if you wanna learn how to write the same code. Because it is NOT explained at all.

    Taking a look at the source code (from the final example page) things become way more clear. But there is no way I could produce that code following the tutorial.

    So, in the end, thanks for a nice piece of code. It was exactly what I was looking for. But I was really looking forward to read an article that could teach me something. Instead I just got frustrated being unable to find so many missing pieces of the whole picture.

  84. 98

    Dear Derek, i badly need the complete souce code of this graph please please provide me the code at my email id. I will be highly grateful to you….!

  85. 99

    Great Post! Very Useful stuff here Thanks!

  86. 100

    Could you guide us, how to change to horizon bar

↑ Back to top