Free Saeed Malekpour, Website Developer

Contact Me

@zoltandulac

Most Popular Posts

  • Cross Browser CSS Transforms – even in IE
  • How to Detect Font-Smoothing Using JavaScript
  • @font-face in Depth
  • Cross Browser HTML5 Drag and Drop
  • Installing Cygwin and FontForge for Windows
  • Cross Browser HTML5 Progress Bars In Depth
  • Creating Cross Browser HTML5 Forms Now, Using modernizr, webforms2 and html5Forms
  • Categories

    Cross Browser HTML5 Progress Bars In Depth

    January 3rd, 2012 by zoltan · 43 Comments

    Update (March 9, 2012):

    I have updated this document to include styling information for Internet Explorer 10.

    Screenshots of HTML5 progress bars with different styles applied. Details given below.

    As a web application developer, progress bars are great when you want to show the user that some action is happening, especially when it can take a long time. They can be animated (like the one in Gmail does when it shows the user how long it is going to take for it to load and initialize), or static (like some shopping cart applications have to show the user how many pages it will take to check out an order). I used to create progress bars using <div> tags, CSS and a litle bit of math, but now I like to do it the HTML5 way using the <progress> tag. This article will discuss how this tag is rendered by default in all operating systems and browsers and how to style the progress tag with CSS, even in browsers that don’t officially support the it. It will also discuss some interesting limitations of all the browser implementations amd show some interesting examples using advanced CSS3 techniques.

    The HTML: Simple

    The HTML for a Progress bar is dead simple:

    <progress max="100" value="60">
      <strong>Progress: 60% done.</strong>
    </progress>
    
    Progress: 60% done.

    Note that the HTML inside the <progress> tag is the fallback for browsers that do not support it. That, unfortunately, includes all versions of IE and Safari so far, as well older versions of Firefox (5.x and lower) and Opera (10.x and lower). Although the fallback is acceptable, we can go a step further and use Lea Verou’s excellent <progress> tag polyfill, which adds pretty much full-support for all of these browsers except for Safari 5 and lower (so you should always put in the fallback HTML just to be on the safe side). Let’s take a look at these screenshots to see what how <progress> looks across the browserverse:

    Windows 7 Windows XP Mac OS X Ubuntu Linux
    Firefox
    Chrome
    IE7-9 (polyfill) N/A
    IE10 N/A
    Safari 5.1+ (polyfill) N/A
    Opera

    Note that:

    • Firefox and Chrome will render the progress bar the same way that the host operating system would … except for Chrome for Linux, which uses it’s own custom style (thanks to Mounir Lamouri for correcting me on this exception).
    • The color of the Opera progress value is always green (more on this later).
    • The browsers that use the polyfill all render the progress bar with a nice bluish gradient effect

    A progress bar can also have an “indeterminate” state, which happens when there is no value attribute.

    <progress max="100">
      <strong>Progress: 60% done.</strong>
    </progress>
    
    Progress: 60% done.

    This effect is used to show that the state of progress is currently unknown (e.g. how long it will take for a web server to initiate the download of a file if is generating it on the fly). How this looks varies from browser to browser as well.

    Windows 7 Windows XP Mac OS X Ubuntu Linux
    Firefox
    Chrome
    IE7-9 (polyfill) N/A
    IE10 N/A
    Safari 5.1+ (polyfill) N/A
    Opera

    Note that:

    • Opera is the only browser that doesn’t distinguish between a progress bar with an indeterminate state and one with a value of zero.
    • All of the other browsers (including the ones that use the polyfill) animate the indeterminate states. (I have opted to not show all the animations here to avoid readers getting seizures … I hear that would be a bad thing).

    One changes the value of the progress bar by changing its DOM node’s .value property. Easy peasy.

    But I Want To Style Them My Way!

    If you are particular in how you want your <progress> tags to look, the good news is that you can pretty much style them any way you want. You must, however, be aware about the browser quirks that can trip you up … and it isn’t all IE’s fault this time! Follow this three-to-four-step process, and you’ll be styling progress bars in your sleep in no time:

    Step 1: Turn off default styling

    The first step is to turn off the default styling in all browsers:

    progress,          /* All HTML5 progress enabled browsers */
    progress[role]     /* polyfill */
    {
    
    	/* Turns off styling - not usually needed, but good to know. */
    	appearance: none;
    	-moz-appearance: none;
    	-webkit-appearance: none;
    
    	/* gets rid of default border in Firefox and Opera. */ 
    	border: none;
    
    	/* Needs to be in here for Safari polyfill so background images work as expected. */
    	background-size: auto;
    	
    	/* Dimensions */
    	width: 400px;
    	height: 60px;
    	
    }
    
    /* Polyfill */
    progress[role]:after {
    	background-image: none; /* removes default background from polyfill */
    }
    
    /* Ensure fallback text doesn't appear in polyfill */
    progress[role] strong {
    	display: none;
    }
    
    
    Progress: 60% done.

    Simple stuff: remove the border and add a specific width and height. I added the second rule to remove the background image inserted by the polyfill’s stylesheet, but if you wanted, you can modify the polyfill’s stylesheet directly (or leave it out completely if you elect not to use the polyfill). The final rule is to ensure the polyfill doesn’t display the fallback content — it assumes that is always wrapped in a <strong> tag, so this may be something you should keep in mind when setting the default content (if you don’t like using a <strong> tag as a wrapper for your fallback content, use whatever tag you like).

    Note that the appearance property (and its vendor-specific brethren) are there to turn off the default operating-system styling on the progress bar — it doesn’t seem like it is really necessary, but I put it here for reference in case it becomes mandatory in the future.

    Step 2: The Progress Bar Background.

    Now let’s change the background color of the progress bar to a light red.

    progress,                          /* Firefox  */ 
    progress[role][aria-valuenow] {    /* Polyfill */
       background: #ffeeee !important; /* !important is needed by the polyfill */
    }
    
    /* Chrome */
    progress::-webkit-progress-bar {
        background: #ffeeee;
    }
    

    Notice that with Firefox and the polyfilled browsers, all you need to do is change the background of just the progress tag itself, while in Chrome (and I assume future versions of Safari) it is necessary to use the -webkit-progress-bar pseudo-element. Note that even though the code inside these rules are the same, you cannot put all of these selectors in one rule: doing so breaks Firefox and Opera (so much for degrading gracefully).

    Step 3: The Progress Bar Value

    Now let’s change the color of progress bar value to black. The CSS is a wee bit longer than it really should be:

    
    /* IE10 */
    progress {
        color: black;
    }
    
    /* Firefox */
    progress::-moz-progress-bar { 
        background: black;	
    }
    
    /* Chrome */
    progress::-webkit-progress-value {
        background: black;
    }
    
    /* Polyfill */
    progress[aria-valuenow]:before  {
        background: black;
    }
    

    Yes, three rules to rule them all! Yes, four rules are needed now if you include IE 10! Again, putting them all together in one selector breaks every browser on the planet (including the polyfilled ones), so we have to write three separate rules with the same CSS properties in them! <sarcasm>Yaaayyy!!!!</sarcasm>

    Note that there is no way that I know of to style the progress bar value in Opera 11.52 and lower. It just stays the same green no matter what you do. :-( If anyone is reading this and knows otherwise, I would be indebted to you to let me know how. Note also that as of this writing, the preview release of Internet Explorer 10 does not allow styling of the progress bar value with an image, only a color using the color attribute, so some of these examples do not look as intended in that browser)

    Step 4: The Indeterminate Value

    This part is optional, and I would only put these rules in if I know I’ll need a style for the indeterminate value (not all applications need it):

    /* Firefox */
    progress:not([value])::-moz-progress-bar { 
      background-image:  url(../images/indeter.gif);	
    }
    
    /* Chrome */
    progress:not([value])::-webkit-progress-bar {
      background-image:  url(../images/indeter.gif);	
    }
    
    /* Polyfill - IE */
    progress[role]{
    	background-image: url(../images/indeter.gif) !important;
    }
    
    /* Polyfill - Safari */
    progress:not([value])  {
    	background-image: url(../images/indeter.gif) !important;
    	background-size: auto;  /* Needs to be in here for Safari */
    }
    

    It even works in Opera! Note that the background-size must be set to auto in order to override the default style in the polyfill. :-)

    See the above CSS in action in a “clean room” page

    That’s Too Basic! I Want Fancy-Pants™ Progress Bars

    So, now that you know the basics, let’s take a look at some more complicated and interesting progress bars:

    Two Image Effect

    This progress bar uses two versions of the same image (one grey-scale, one color) to differentiate between the progress bar background and value:

    See the above example in action in a “clean room” page

    Unfortunately, this example doesn’t work in Opera and IE10, since at this time one cannot style the progress bar value with an image in those browsers.

    Gradients

    Note that not only can you use background-colors and -images, but also use the variety of gradients that are available for developers today in supported browsers (this does not include IE9 and lower). To prove this, I took Chris Croyer beautiful <div> style progress bars from his blog post on CSS3 based progress bars and HTML5-ified™ them here:

    Unfortunately, due to CSS gradients being implemented by the browser vendors using vendor-specific prefixes, the CSS tends to be a wee long. Here is the CSS of the first example (scroll the code to see the whole lot of it):

    /*
     * Gradient Shadow
     */
    
    /* All HTML5 progress enabled browsers */
    progress.example3 {
    
    	/* Turns off styling - not usually needed, but good to know. */
    	appearance: none;
    	-moz-appearance: none;
    	-webkit-appearance: none;
    	/* gets rid of default border in Firefox and Opera. */
    	border: solid #cccccc 5px;
    	border-radius: 10px;
    	/* Dimensions */
    	width: 238px;
    	height: 45px;
    }
    
    /* Polyfill */
    progress.example3[role]:after {
    	background-image: none; /* removes default background from polyfill */
    }
    
    /*
     * Background of the progress bar background
     */
    
    /* Firefox and Polyfill */
    progress.example3 {
    	background: #cccccc !important; /* !important only needed in polyfill */
    }
    
    /* Chrome */
    progress.example3::-webkit-progress-bar {
    	background: #cccccc;
    }
    
    /*
     * Background of the progress bar value
     */
    
    /* Firefox */
    progress.example3::-moz-progress-bar {
    	border-radius: 5px;
    	background-image: -moz-linear-gradient(
    		center bottom,
    		rgb(43,194,83) 37%,
    		rgb(84,240,84) 69%
    	);
    }
    
    /* Chrome */
    progress.example3::-webkit-progress-value {
    	border-radius: 5px;
    	background-image: -webkit-gradient(
    		linear,
    		left bottom,
    		left top,
    		color-stop(0, rgb(43,194,83)),
    		color-stop(1, rgb(84,240,84))
    	);
    	background-image: -webkit-linear-gradient(
    		center bottom,
    		rgb(43,194,83) 37%,
    		rgb(84,240,84) 69%
    	);
    }
    
    /* Polyfill */
    progress.example3[aria-valuenow]:before {
    	border-radius: 5px;
    	background-image: -moz-linear-gradient(
    		center bottom,
    		rgb(43,194,83) 37%,
    		rgb(84,240,84) 69%
    	);
    	background-image: -ms-linear-gradient(
    		center bottom,
    		rgb(43,194,83) 37%,
    		rgb(84,240,84) 69%
    	);
    	background-image: -o-linear-gradient(
    		center bottom,
    		rgb(43,194,83) 37%,
    		rgb(84,240,84) 69%
    	);
    	
    }
    

    This example doesn’t work in any version of IE (since that browser can only change the color, not the background image, of a progress bar value) or Opera (since it can’t style the progress bar at all). Also, note that I did not use the Gradient filter to polyfill CSS3 gradients in IE6-9. This is because Visual Filters don’t work in CSS3 pseudo-elements like :before or :after. Oh well.

    See the above CSS in action in a “clean room” page

    Monkeys!

    What blog post about HTML5 progress tags would be complete without monkeys? These simians appear in all browser except for IE8 and lower (as explained below).

    Apologies to the great Banksy — it’s not his monkey but one grabbed from this Animated GIF site and converted into a CSS sprite using André Gil’s super-cool Gif2TileSet tool. I took this sprite and animated the monkey using blitting whenever the progress bar changes values (thanks to my friend and colleague Noel Tibbles for turning me on to this technique).

    Note the HTML has an extra <div> tag so the monkey has a place to live:

    <progress class="monkey" min="0" max="100" value="60"></progress>
    <div class="after"></div>
    

    I wish that I could have used :after (or ::after) rules instead, but these pseudo-elements don’t work with the progress tags in any browser that doesn’t use the polyfill. And no, :before doesn’t work either. I have no idea why it doesn’t work, but it’s a shame — using them would be perfect to get rid of the extra markup.

    The CSS that makes the monkey animate when the progress bar changes values is here:

    progress.monkey[value="0"] +  .after{
    	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif');
    } 
    
    progress.monkey[value^="1"] +  .after {
    	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif') 0  -77px ;
    }
    
    progress.monkey[value^="2"] +  .after {
    	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif') 0  -154px ;
    }
    
    progress.monkey[value^="3"] +  .after,
    progress.monkey[value="100"] +  .after  {
    	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif') 0  -231px !important ;
    }
    
    progress.monkey[value^="4"] +  .after {
    	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif') 0  -308px ;
    }
    
    progress.monkey[value^="5"] +  .after {
    	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif') 0  -385px ;
    }
    
    progress.monkey[value^="6"] +  .after {
    	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif') 0  -462px ;
    }
    
    progress.monkey[value^="7"] +  .after {
    	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif') 0  -539px ;
    }
    
    progress.monkey[value^="8"] +  .after {
    	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif') 0  -616px ;
    }
    
    progress.monkey[value^="9"] +  .after {
    	background: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif') 0  -693px ;
    }
    

    Each of these rules are applied when the first digit changes in the progress bar, which is done using the ^= attribute rules. This works because the progress bar goes from 0 – 100 and the progress bar increments by 10. They monkeys don’t appear in IE8 and under because of it’s lack of support of the ^= attribute selector (but it works well in IE9).

    Note that this would be much easier if CSS allowed us to combine the CSS3 calc() and attr() attributes together like Lea Verou dreams about in one of her blog posts:

    /*
     * Don't try this - it doesn't work in any browser, but it would be nice if it did.
     */
    
    progress.monkey::after {
       background-image: url('/blog/wp-content/uploads/2011/12/monkeyBlit.gif');
       background-position-x: 0;
       background-position-y: calc(-77 * attr(value), 'px');
    }
    

    Hopefully this will come to pass in the future.

    See the above CSS in action in a “clean room” page

    Speedometer

    My last example is radically different than the others. How about we apply the speedometer metephor to the progress bar with some fancy-pants CSS3? This example in all browsers except IE8 and lower (due to lack of support for native CSS3 transform)

    The CSS is similar to the monkey example in that I add an extra <div> after the progress tag, except that it has an image of a pointer inside of it.

    <div id="progressContainer">
      <progress id="rot" class="example_r" min="0" max="100" value="60"></progress>
      <div data-arrow-for="rot" class="arrow"><img src="/blog/wp-content/uploads/2012/01/hand.png" /></div>
    </div>
    

    I wrapped both these tags inside a relatively positioned container <div>. This is so I could absolutely position both the progress bar and the arrow in order for them to line up properly. I make the progress bar into a semi-circle by using border-radius and part of a photo from Flickr user ‘listener42′

    progress.example_r {
    
    	/* gets rid of default border in Firefox and Opera. */
    	border: solid 1px black;
    	display: inline-block;
    	
    	/* Produces the semi-circle */
    	border-radius: 238px 238px 0 0;
    
    	/* Dimensions */
    	width: 238px;
    	height: 126px;
    	padding: 0;
    
            /* IE needs this to hide the native progress bar value */
            color: transparent;
    }
    

    … and make the arrow rotate as the progress bar increments by using CSS transforms:

    progress.example_r[value="0"] + .arrow {
    	-moz-transform: rotate(270deg);
    	-webkit-transform: rotate(270deg);
    	-o-transform: rotate(270deg);
    	-ms-transform: rotate(270deg);
    }
    
    progress.example_r[value^="1"]:not([value="1"]):not([value="100"]) + .arrow {
    	-moz-transform: rotate(288deg);
    	-webkit-transform: rotate(288deg);
    	-o-transform: rotate(288deg);
    	-ms-transform: rotate(288deg);
    }
    
    progress.example_r[value^="2"]:not([value="2"]) + .arrow {
    	-moz-transform: rotate(306deg);
    	-webkit-transform: rotate(306deg);
    	-o-transform: rotate(306deg);
    	-ms-transform: rotate(306deg);
    }
    
    progress.example_r[value^="3"]:not([value="3"]) + .arrow {
    	-moz-transform: rotate(324deg);
    	-webkit-transform: rotate(324deg);
    	-o-transform: rotate(324deg);
    	-ms-transform: rotate(324deg);
    }
    
    progress.example_r[value^="4"]:not([value="4"]) + .arrow {
    	-moz-transform: rotate(342deg);
    	-webkit-transform: rotate(342deg);
    	-o-transform: rotate(342deg);
    	-ms-transform: rotate(342deg);
    }
    
    progress.example_r[value^="5"]:not([value="5"]) + .arrow {
    	-moz-transform: rotate(360deg);
    	-webkit-transform: rotate(360deg);
    	-o-transform: rotate(360deg);
    	-ms-transform: rotate(360deg);
    }
    
    progress.example_r[value^="6"]:not([value="6"]) + .arrow {
    	-moz-transform: rotate(378deg);
    	-webkit-transform: rotate(378deg);
    	-o-transform: rotate(378deg);
    	-ms-transform: rotate(378deg);
    }
    
    progress.example_r[value^="7"]:not([value="7"]) + .arrow {
    	-moz-transform: rotate(396deg);
    	-webkit-transform: rotate(396deg);
    	-o-transform: rotate(396deg);
    	-ms-transform: rotate(396deg);
    }
    
    progress.example_r[value^="8"]:not([value="8"]) + .arrow {
    	-moz-transform: rotate(414deg);
    	-webkit-transform: rotate(414deg);
    	-o-transform: rotate(414deg);
    	-ms-transform: rotate(414deg);
    }
    
    progress.example_r[value^="9"]:not([value="9"]) + .arrow {
    	-moz-transform: rotate(432deg);
    	-webkit-transform: rotate(432deg);
    	-o-transform: rotate(432deg);
    	-ms-transform: rotate(432deg);
    }
    
    progress.example_r[value="100"] + .arrow {
    	-moz-transform: rotate(450deg);
    	-webkit-transform: rotate(450deg);
    	-o-transform: rotate(450deg);
    	-ms-transform: rotate(450deg);
    }
    

    Again, the CSS would be much smaller in size if I could use calc() and attr() together, but again, oh well. Furthermore, that this example doesn’t work in Opera very well because we cannot turn of the green in the progress bar value. Although we can hide this bar in IE10 by setting the progress bar’s color to transparent a thin line can be seen where the end of the progresss bar used to be. Ugh… :-(

    See the above CSS in action in a “clean room” page

    Summary of Gotchas

    As mentioned before, there are a few annoyances I have found with they way the browsers have implemented HTML5 progress bars:

    1. You cannot use :before/::before or :after/::after pseudo-elements on the progress element. Why this is not allowed is unclear to me, and I hope this is allowed in the future.
    2. Safari 5.0 and lower cannot use the polyfill, so you should always use the fallback HTML inside the <progress> tag.
    3. It seems like it is impossible to change Opera’s progress bar value style to anything besides green.
    4. While you can change the progress bar value color in IE10, as far as I know it is impossible to apply a background image to it.
    5. There is a small bug in the polyfill when applying borders to the progress bar. I have a fix that has been submitted as a pull request and I assume being reviewed, but in the meantime, you can get my forked version of the polyfill (with the bug fix) on GitHub.

    Help Me Keep This Page Up-To-Date!

    If you find out more information about the HTML5 progress tag, I’d love to hear from you! Please let me know in the comments below. I will add relevant information to the above article and credit you fully. :-)

    Tags: CSS3 · Forms · gradients · HTML · HTML5 · Polyfills · progress

    43 responses so far ↓
    • 3 Cyberdemon // Jan 4, 2012 at 12:56 am

      Mind = blown.

    • 4 sabari // Jan 4, 2012 at 1:10 am

      its amazing and very useful to me.. thank u :)

    • 5 Camilo // Jan 4, 2012 at 2:07 am

      Great article!
      It would be nice if select and input files actually have a similar selectors to customize them like that.

    • 6 TheSisb // Jan 4, 2012 at 4:46 am

      This is indeed an excellent, in-depth article.
      Thanks for taking the time to explain this so fully!

    • 7 Vladimir // Jan 4, 2012 at 5:37 am

      Great article, thanks! What about IE7-8, and fallback? Some small jQuery wrapper or pure js plugin will be useful (just a bg position is ok for old browsers)

    • 9 Ryan // Jan 4, 2012 at 9:19 am

      Superb :) Filled in a few blanks but like to see it out there!

    • 10 zoltan // Jan 4, 2012 at 9:50 am

      @Vladamir: I believe you are refer to the last example, and yes, it is quite possible to use a js library like my own cssSandpaper to do the animated rotation of the spedometer dial. I just wanted to show how it is now possible to do complex styling of progress elements without any additional JavaScript.

    • 11 Samiullah Khan // Jan 4, 2012 at 9:54 am

      Great Analogy of Html5 progress bars;
      The one with gradients are promising!

    • 12 Ed // Jan 4, 2012 at 10:01 am

      Thanks for sharing this information. The summary of gotchas is nice. The second gotcha, about Safari 5.0 seems to have something missing. If I have followed correctly, I think you meant to point out that with Safari 5.0 and lower you should always use the fallback markup. If I haven’t followed correctly, I’ll blame my lack of coffee this morning!

    • 13 NobbZ // Jan 4, 2012 at 10:30 am

      Thank you! And all the past I thought is not stylable because I did not found any informations about styling it… So I sticked to divs until today…

      I bookmarked this page and hope it will help me in the future, to rebuild my project!

    • 14 zoltan // Jan 4, 2012 at 12:04 pm

      @Ed: Oops. Typo.. thanks for pointing it out. You are correct… fallback text is good, even when using the polyfill. :)

    • 15 Steve // Jan 4, 2012 at 12:28 pm

      This is really cool! I’m lovin’ HTML5. Thanks for the write up.

    • 16 Marco // Jan 4, 2012 at 1:56 pm

      Awesome stuff Zoltan. I definitely will go back to this when I have a project that needs it. Thank you!!

    • 17 左撇子 // Jan 4, 2012 at 9:11 pm

      that is really cool, nice post! Thank you!

    • 18 Gundars // Jan 5, 2012 at 2:16 pm

      Awesome! CTRL+D

    • 19 Diseño de Paginas Web en Tijuana // Jan 5, 2012 at 2:34 pm

      I liked the article would use some of this in future website but with better design! Thanks for sharing.

    • 20 Alex // Jan 5, 2012 at 2:35 pm

      Thanks for the highly useful info! I’m impressed at Opera’s consistency across OS in the default bars – and I love the speedometer example.

    • 21 Subash Aryal // Jan 6, 2012 at 12:24 am

      A good read and easily understood. nice post. Thank you, keep up doing good stuffs like this :)

      me @webaryal in Twitter…

    • 22 zoltan // Jan 6, 2012 at 12:29 am

      @Vladimir: Apologies! I was taking a look at this article in IE8 and noticed that the progress bars were not showing up due to the stylesheet not being picked up correctly, which explains your comment. I have fixed this mistake. Thanks for bringing this to my attention. :-)

    • 23 Vladimir // Jan 6, 2012 at 12:40 am

      @zoltan: You welcome!

    • 24 Darto KLoning // Jan 6, 2012 at 5:01 am

      This is so much awesome on the simplicity.

    • 25 mohsen // Jan 6, 2012 at 9:12 am

      thank you ,very useful

    • 26 Jason // Jan 11, 2012 at 9:48 pm

      This looks great – i have been really getting into HTML5 but obviously not enough as i didnt even realise this existed! I would love to implement this as a page / image preloader – can anyone provide a simple example or link to this?

    • 27 zoltan // Jan 12, 2012 at 9:17 am

      @Jason: Out of coincidence, the new article I am working on talks about that. Stay tuned! :)

    • 28 Jason // Jan 12, 2012 at 5:52 pm

      Good stuff Zoltan, you’re site is now in my Xmarks! :)

    • 29 zoltan // Jan 17, 2012 at 1:01 am

      @Jason: Take a look at my new blog post for an image preloader example.

    • 30 Beben Koben // Jan 25, 2012 at 10:56 pm

      experience anymore…hohoho ty

    • 31 Federico // Feb 1, 2012 at 10:07 am

      ::before and ::after do not work cause they are create _inside_ the PROGRESS element. And content of this element is replaced with a progress bar. The same goes for the OBJECT element.

    • 32 digitalcraftstudios // Mar 12, 2012 at 5:54 pm

      Thanks, will use classic gif animation activity indicator as fall back

    • 33 zoltan // Mar 13, 2012 at 10:38 pm

      @Federico: Even though the content would be created inside the progress element, I thought the content would appear inside the progress bar, and could be moved outside the element using absolute positioning (like it would with a div element. It’s too bad, since it would be nice to be able to use these pseudo-elements to do some pretty cool styling. :-/

    • 34 RAHUL // Apr 14, 2012 at 2:36 am

      awesome, very useful post…

    • 35 Thomas Vanhoutte // Apr 24, 2012 at 1:38 pm

      That is what I call ‘progress’, HTML5 will rock the internet!

    • 36 Jo // Aug 15, 2012 at 2:50 pm

      Hi,

      Using it vertically, is it possible?
      And using multiple color? 0% = red 100%=green ?

    • 37 zoltan // Aug 24, 2012 at 4:27 pm

      @Jo: Yes, both are possible. Stack Overflow has a great discussion on vertical progress bars (or you can just use CSS3 transforms to turn the progress 90 degrees if you are feeling very lazy). As for the multiple color issue, I am assuming that you mean that the bar will be red at 0% and as the number approaches 100%, the hue of the progress bar will change gradually to green. If that is the case, you can use a variation of the attribute selectors used in the monkey example to do this. I will, however, leave it as an exercise for the reader to implement it (or until I have a few cycles to actually do this myself).

    • 38 Onixmediadesign // Sep 10, 2012 at 7:04 pm

      Excelent post thank you very much!

    • 39 Nilesh // Oct 31, 2012 at 3:11 am

      Awesome… : )
      Thanks a lot…

    • 40 Nima // Jan 5, 2013 at 9:26 am

      It was mind blowing, thanks.
      one of the best tutorials I have ever seen.

    • 41 Joker // Feb 28, 2013 at 1:25 am

      Whats the code for the button Test Progress Bar?

    • 43 zoltan // Mar 7, 2013 at 7:20 pm

      @Joker: I’ll answer this question from two different perspectives:

      1. In general, if you want to change the value of a progress bar DOM element, you simply set the .value property of the object.
      2. For my examples specifically, here is a simplified version of the jQuery code, given the “Test Progress Bar” button has a class of progressTest:
        function initDemo () {
            $('.progressTest').click(function (e) {
                e.preventDefault();
                var id = $(e.target).attr('data-for');
                
                var el = $('#' + id ).get(0);
                
                //$arrow.addClass('noTransition');
                //el.value=0;
                setTimeout(function () {
                    startHelper(el);
                }, 200);
            });
        }
        
        function startHelper(el) {
            startTimeout(0, el, 100);    
        }
            
        function startTimeout(n, el, ms) {
             
            var val = parseInt(el.value);
            el.value = n;
            
            if (parseInt(el.value) < 100) {
                setTimeout(function() {
                    startTimeout(n+10, el, ms)
                }, ms);
            }    
        }
        
        $(document).ready(initDemo);
        

        You can see the exact code the blog post uses if you’d like.

    Give Feedback

    Don't be shy! Give feedback and join the discussion.

    Please Note: If you are asking for help using the information on this page or if you are reporting a bug with the code featured here, please include a URL that shows the problem you are experiencing along with the browser/version number/operating system combination where the issue manifests itself. Without this information, I may not be able to respond.

    An orange star denotes a required field.