Bootstrap progress bar in 100 images for older browsers

These are assumptions taken here:

  • Bootstrap progress bars are nice
  • They do not work in IE 6-9 (I really wonder why 24% of web users don’t upgrade their browsers):
    "Progress bars use CSS3 gradients, transitions, and animations to achieve
    all their effects. These features are not supported in IE7-9 or older
    versions of Firefox."
  • I needed a progress bar for a web form that would work in all browsers
  • I’m calculating how much of a web form is completed with AngularJS and change the progress bar on he fly.

Let’s start.

1. Create 100 progress bars using a php loop and a Bootstrap progress bar code:

 <!doctype html>
 <html>
    <head>    
        <link rel="stylesheet" href="lib/bootstrap/css/bootstrap.min.css">
        <script src="lib/bootstrap/js/bootstrap.min.js"></script>
    </head>
    <body>

        <div id="progress_bar" style="width: 500px; margin: 10px auto 0 auto">
            <?php
            for ($i=0; $i<101; $i++) { 
                echo '  <div class="progress" style="margin: 2px">
                            <div class="bar" style="width: '.$i.'%"></div>
                        </div>';
            }                    
            ?>
        </div>
    </body>
 </html>

It is possible to use other colours and stripes, etc … but I’ll use simplest progress bar. Keep in mind that my outer div is 500px wide as this is the size of a progress bar I wanted.

2. Crop the progress bars from a web page produces by the above code

The simplest way is to use Awesome screenshot extension for Chrome, Safari or Firefox. It is also good to cut down the image size with e.g. re-saving it for the web so it would be smaller in size (not resolution).

I ended up with this image (original size can be downloaded here):

This can be already the end of the story. The only thing wee need is to use this image as a background of a div and slide up or down based on the percentage we want to show.

3. Show the progress bar

3.1 Using CSS background-position and AngularJS binding

 <div style="float: left;">Progress: </div>
 <div style="width: 500px; height: 22px; float: left;
                  background-image:url('progressbar_small.png'); 
                  background-position:0px -{{Math.round(22*(percentage))}}px;">
 </div>

Each progress bar is 22px high and I multiply it with the percentage I calculate based on how much of the form is filled in. I also use the Math JS in binding for multiplication (maybe there’s a better way but I’m not aware of any). To do this I had to define the Math object in my $scope this way $scope.Math = window.Math; 

For some reason the above did not work in IE 8 (which I really care about). Although it apparently works on some web sites. So i decided to slice up the above image in 100 images.

3.2 Using individual images

This is not the optimum solution as for every change there is an Ajax get call to retrieve a desired image. We did this only once in the above example.

This procedure was also explained in a previous post.

First I sliced up the image with ImageMagick using a crop flag (the second command should be in one line) using a bash one line script:

 mk@here/$ ls
 progressbar_small.png

 mk@here/$ for((i=0; i<101; i++)) ; do n=$[i*22]; \ 
          convert progressbar_small.png -crop 500x22+0+$n +repage progressbar${i}.png; \
          done

 mk@here/$ ls
 progressbar0.png    progressbar32.png  progressbar56.png  progressbar7.png
 ...
 progressbar2.png    progressbar53.png  progressbar77.png  progressbar_small.png

The -crop flag slices up images 500px wide and 22px high and starts at 0px on the X axis and goes down 22*i where i runs from 0 to 100. The end results are 100 images.

And finally the HTML bit:

 <div style="float: left;">Progress: </div>
 <div style="width: 500px; height: 22px; float: left;">
     <img src=progressbar{{Math.round(22*(percentage))}}.png">
 </div>

All  images are available in this zip file.

I hope this can help someone.

Any other suggestions greatly appreciated.

A big thank you to Tine for all the suggestions and help.