{"id":4016,"date":"2012-01-03T03:08:54","date_gmt":"2012-01-03T07:08:54","guid":{"rendered":"http:\/\/www.useragentman.com\/blog\/?p=4016"},"modified":"2013-03-07T19:24:01","modified_gmt":"2013-03-07T23:24:01","slug":"cross-browser-html5-progress-bars-in-depth","status":"publish","type":"post","link":"http:\/\/www.useragentman.com\/blog\/2012\/01\/03\/cross-browser-html5-progress-bars-in-depth\/","title":{"rendered":"Cross Browser HTML5 Progress Bars In Depth"},"content":{"rendered":"<div class=\"importantNotes\">\n<h3>Update (March 9, 2012):<\/h3>\n<p>I have updated this document to include styling information for Internet Explorer 10.<\/p>\n<\/div>\n<p><div id=\"attachment_4224\" style=\"width: 260px\" class=\"wp-caption alignleft\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-4224\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2012\/01\/intro.png\" alt=\"\" title=\"intro\" width=\"250\" height=\"180\" class=\"size-full wp-image-4224\" \/><p id=\"caption-attachment-4224\" class=\"wp-caption-text\">Screenshots of HTML5 progress bars with different styles applied.  Details given below.<\/p><\/div> As a web application developer,<strong> progress bars are great when you want to show the user that some action is happening,<\/strong> especially when it can take a long time.  They can be <strong>animated<\/strong> (like the one in Gmail does when it shows the user how long it is going to take for it to load and initialize), <strong>or static<\/strong> (like some shopping cart applications have to show the user how many pages it will take to check out an order).  I used to <a href=\"http:\/\/css-tricks.com\/css3-progress-bars\/\">create progress bars using <code>&lt;div&gt;<\/code> tags, CSS and a litle bit of math<\/a>, but now I like to do it the HTML5 way using the <code>&lt;progress&gt;<\/code> tag.  This article will discuss <strong>how this tag is rendered by default<\/strong> in all operating systems and browsers and how to <strong>style the <code>progress<\/code> tag with CSS<\/strong>, even in browsers that don&#8217;t officially support the it.  It will also discuss some interesting <strong>limitations of all the browser implementations<\/strong> amd show some <strong>interesting examples using advanced CSS3 techniques.<\/strong><\/p>\n<h2>The HTML: Simple<\/h2>\n<p>The HTML for a Progress bar is dead simple:<\/p>\n<blockquote class=\"code\">\n<pre>\r\n&lt;progress max=\"100\" value=\"60\"&gt;\r\n  &lt;strong&gt;Progress: 60% done.&lt;\/strong&gt;\r\n&lt;\/progress&gt;\r\n<\/pre>\n<\/blockquote>\n<div class=\"example\">\n<progress max=\"100\" value=\"60\"><strong>Progress: 60% done.<\/strong><\/progress>\n<\/div>\n<p><strong>Note that the HTML inside the <code>&lt;progress&gt;<\/code> tag is the fallback for browsers that do not support it.<\/strong>  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 <strong><a href=\"http:\/\/lea.verou.me\/\">Lea Verou&#8217;s<\/a> excellent <a href=\"http:\/\/lea.verou.me\/2011\/07\/a-polyfill-for-html5-progress-element-the-obsessive-perfectionist-way\/\"><code>&lt;progress&gt;<\/code> tag polyfill<\/a><\/strong>, which adds pretty much full-support for all of these browsers <strong>except for Safari 5 and lower<\/strong> (so you should <em><strong>always put in the fallback HTML just to be on the safe side<\/strong><\/em>).  Let&#8217;s take a look at these screenshots to see what how <code>&lt;progress&gt;<\/code> looks across the browserverse:<\/p>\n<table class=\"dataTable\">\n<thead>\n<tr>\n<th><\/th>\n<th>Windows 7<\/th>\n<th>Windows XP<\/th>\n<th>Mac OS X<\/th>\n<th>Ubuntu Linux<\/th>\n<\/thead>\n<tbody>\n<tr>\n<th>Firefox<\/th>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/defaultFirefoxWin.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/defaultFirefoxWinXP.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/defaultFirefoxMac.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/defaultFirefoxLinux.png\" alt=\"\"  \/><\/td>\n<\/tr>\n<tr>\n<th>Chrome<\/th>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/defaultChromeWin.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/defaultChromeWinXP.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/defaultChromeMac.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/defaultChromeLinux.png\" alt=\"\"  \/><\/td>\n<\/tr>\n<tr>\n<th>IE7-9 (polyfill)<\/th>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/defaultSafariWin_poly.png\" alt=\"\"  \/><\/td>\n<td colspan=\"3\" class=\"na\">N\/A<\/td>\n<\/tr>\n<tr>\n<th>IE10<\/th>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2012\/01\/defaultIE10Win.png\" alt=\"\"  \/><\/td>\n<td colspan=\"3\" class=\"na\">N\/A<\/td>\n<\/tr>\n<tr>\n<th>Safari 5.1+ (polyfill)<\/th>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/defaultSafariWin_poly.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/defaultSafariWin_poly.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/defaultSafariWin_poly.png\" alt=\"\"  \/><\/td>\n<td class=\"na\">N\/A<\/td>\n<\/tr>\n<tr>\n<th>Opera<\/th>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/defaultOperaWin.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/defaultOperaWin.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/defaultOperaMac.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/defaultOperaLinux.png\" alt=\"\"  \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Note that:<\/p>\n<ul>\n<li>Firefox and Chrome will render the progress bar the same way that the host operating system would &#8230; except for Chrome for Linux, which uses it&#8217;s own custom style (thanks to <a href=\"http:\/\/blog.oldworld.fr\/\">Mounir Lamouri<\/a> for correcting me on this exception).<\/li>\n<li>The color of the Opera progress value is always green (more on this later).<\/li>\n<li>The browsers that use the polyfill all render the progress bar with a nice bluish gradient effect<\/li>\n<\/ul>\n<p>A progress bar <strong>can also have an <em>&#8220;indeterminate&#8221;<\/em> state<\/strong>, which happens when there is <strong>no value attribute<\/strong>. <\/p>\n<blockquote class=\"code\">\n<pre>\r\n&lt;progress max=\"100\"&gt;\r\n  &lt;strong&gt;Progress: 60% done.&lt;\/strong&gt;\r\n&lt;\/progress&gt;\r\n<\/pre>\n<\/blockquote>\n<div class=\"example\">\n<progress max=\"100\" ><strong>Progress: 60% done.<\/strong><\/progress>\n<\/div>\n<p>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.<\/p>\n<table class=\"dataTable\">\n<thead>\n<tr>\n<th><\/th>\n<th>Windows 7<\/th>\n<th>Windows XP<\/th>\n<th>Mac OS X<\/th>\n<th>Ubuntu Linux<\/th>\n<\/thead>\n<tbody>\n<tr>\n<th>Firefox<\/th>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/indeterFirefoxWin.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/indeterFirefoxWinXP.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/indeterFirefoxMac.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/indeterFirefoxLinux.png\" alt=\"\"  \/><\/td>\n<\/tr>\n<tr>\n<th>Chrome<\/th>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/indeterChromeWin.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/indeterChromeWinXP.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/indeterChromeMac.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/indeterChromeLinux.png\" alt=\"\"  \/><\/td>\n<\/tr>\n<tr>\n<th>IE7-9 (polyfill)<\/th>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/indeterSafariWin_poly.png\" alt=\"\"  \/><\/td>\n<td colspan=\"3\" class=\"na\">N\/A<\/td>\n<\/tr>\n<tr>\n<th>IE10<\/th>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2012\/01\/indeterIE10Win.png\" alt=\"\"  \/><\/td>\n<td colspan=\"3\" class=\"na\">N\/A<\/td>\n<\/tr>\n<tr>\n<th>Safari 5.1+ (polyfill)<\/th>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/indeterSafariWin_poly.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/indeterSafariWin_poly.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/indeterSafariWin_poly.png\" alt=\"\"  \/><\/td>\n<td class=\"na\">N\/A<\/td>\n<\/tr>\n<tr>\n<th>Opera<\/th>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/indeterOperaWin.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/indeterOperaWin.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/indeterOperaMac.png\" alt=\"\"  \/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2011\/12\/indeterOperaLinux.png\" alt=\"\"  \/><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Note that:<\/p>\n<ul>\n<li>Opera is the only browser that doesn&#8217;t distinguish between a progress bar with an indeterminate state and one with a value of zero.<\/li>\n<li>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 &#8230; I hear that would be a bad thing).<\/li>\n<\/ul>\n<p>One changes the value of the progress bar by changing its DOM node&#8217;s <code>.value<\/code> property.  Easy peasy.<\/p>\n<h2>But I Want To Style Them My Way!<\/h2>\n<p>If you are particular in how you want your <code>&lt;progress&gt;<\/code> tags to look, the good news is that <strong>you can pretty much style them any way you want<\/strong>.  You must, however, <strong>be aware about the browser quirks<\/strong> that can trip you up &#8230; and it isn&#8217;t all IE&#8217;s fault this time!  Follow this three-to-four-step process, and you&#8217;ll be styling progress bars in your sleep in no time:<\/p>\n<h3>Step 1: Turn off default styling<\/h3>\n<p>The first step is to turn off the default styling in all browsers:<\/p>\n<blockquote class=\"code\">\n<pre>\r\nprogress,          \/* All HTML5 progress enabled browsers *\/\r\nprogress[role]     \/* polyfill *\/\r\n{\r\n\r\n\t\/* Turns off styling - not usually needed, but good to know. *\/\r\n\tappearance: none;\r\n\t-moz-appearance: none;\r\n\t-webkit-appearance: none;\r\n\r\n\t\/* gets rid of default border in Firefox and Opera. *\/ \r\n\tborder: none;\r\n\r\n\t\/* Needs to be in here for Safari polyfill so background images work as expected. *\/\r\n\tbackground-size: auto;\r\n\t\r\n\t\/* Dimensions *\/\r\n\twidth: 400px;\r\n\theight: 60px;\r\n\t\r\n}\r\n\r\n\/* Polyfill *\/\r\nprogress[role]:after {\r\n\tbackground-image: none; \/* removes default background from polyfill *\/\r\n}\r\n\r\n\/* Ensure fallback text doesn't appear in polyfill *\/\r\nprogress[role] strong {\r\n\tdisplay: none;\r\n}\r\n\r\n<\/pre>\n<\/blockquote>\n<div class=\"example\">\n<progress class=\"example1 a\" min=\"0\" max=\"100\" value=\"50\">\n<strong>Progress: 60% done.<\/strong>\n<\/progress>\n<\/div>\n<p>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&#8217;s stylesheet, but if you wanted, you can  modify the polyfill&#8217;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&#8217;t display the fallback content &mdash; it assumes that is always wrapped in a <code>&lt;strong&gt;<\/code> tag, so this may be something you should keep in mind when setting the default content (if you don&#8217;t like using a <code>&lt;strong&gt;<\/code> tag as a wrapper for your fallback content, use whatever tag you like).<\/p>\n<p>Note that the <code>appearance<\/code> property (and its vendor-specific brethren) are there to turn off the default operating-system styling on the progress bar &mdash; it doesn&#8217;t seem like it is really necessary, but I put it here for reference in case it becomes mandatory in the future.<\/p>\n<h3>Step 2: The Progress Bar Background.<\/h3>\n<p>Now let&#8217;s change the background color of the progress bar to a light red.  <\/p>\n<blockquote class=\"code\">\n<pre>\r\nprogress,                          \/* Firefox  *\/ \r\nprogress[role][aria-valuenow] {    \/* Polyfill *\/\r\n   background: #ffeeee !important; \/* !important is needed by the polyfill *\/\r\n}\r\n\r\n\/* Chrome *\/\r\nprogress::-webkit-progress-bar {\r\n    background: #ffeeee;\r\n}\r\n<\/pre>\n<\/blockquote>\n<div class=\"example\">\n<progress class=\"example1 a b\" min=\"0\" max=\"100\" value=\"50\"><\/progress>\n<\/div>\n<p>Notice that with Firefox and the polyfilled browsers, all you need to do is change the background of just the <code>progress<\/code> tag itself, while in Chrome (and I assume future versions of Safari) it is necessary to use the <code>-webkit-progress-bar<\/code> pseudo-element. Note that even though the code inside these rules are the same,<strong> you cannot put all of these selectors in one rule<\/strong>: doing so breaks Firefox and Opera (so much for degrading gracefully).<\/p>\n<h3>Step 3: The Progress Bar Value<\/h3>\n<p>Now let&#8217;s change the color of progress bar value to black.  The CSS is a <em>wee bit longer than it really should be<\/em>:<\/p>\n<blockquote class=\"code\">\n<pre>\r\n\r\n\/* IE10 *\/\r\nprogress {\r\n    color: black;\r\n}\r\n\r\n\/* Firefox *\/\r\nprogress::-moz-progress-bar { \r\n    background: black;\t\r\n}\r\n\r\n\/* Chrome *\/\r\nprogress::-webkit-progress-value {\r\n    background: black;\r\n}\r\n\r\n\/* Polyfill *\/\r\nprogress[aria-valuenow]:before  {\r\n    background: black;\r\n}\r\n<\/pre>\n<\/blockquote>\n<div class=\"example\">\n<progress class=\"example1 a b c\" min=\"0\" max=\"100\" value=\"50\"><\/progress>\n<\/div>\n<p><strike>Yes, three rules to rule them all!<\/strike> Yes, <strong>four<\/strong> 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! &lt;sarcasm&gt;Yaaayyy!!!!&lt;\/sarcasm&gt;<\/p>\n<p><strong>Note that there is no way that I know of to style the progress bar value in Opera 11.52 and lower.<\/strong>  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, <strong>the preview release of Internet Explorer 10 does not allow styling of the progress bar value with an image<\/strong>, only a color using the <code>color<\/code> attribute, so some of these examples do not look as intended in that browser)<\/p>\n<h3>Step 4: The Indeterminate Value<\/h3>\n<p>This part is optional, and I would only put these rules in if I know I&#8217;ll need a style for the indeterminate value (not all applications need it):<\/p>\n<blockquote class=\"code\">\n<pre>\r\n\/* Firefox *\/\r\nprogress:not([value])::-moz-progress-bar { \r\n  background-image:  url(..\/images\/indeter.gif);\t\r\n}\r\n\r\n\/* Chrome *\/\r\nprogress:not([value])::-webkit-progress-bar {\r\n  background-image:  url(..\/images\/indeter.gif);\t\r\n}\r\n\r\n\/* Polyfill - IE *\/\r\nprogress[role]{\r\n\tbackground-image: url(..\/images\/indeter.gif) !important;\r\n}\r\n\r\n\/* Polyfill - Safari *\/\r\nprogress:not([value])  {\r\n\tbackground-image: url(..\/images\/indeter.gif) !important;\r\n\tbackground-size: auto;  \/* Needs to be in here for Safari *\/\r\n}\r\n<\/pre>\n<\/blockquote>\n<div class=\"example\">\n<progress class=\"example1 a b c d\" min=\"0\" max=\"100\"><\/progress>\n<\/div>\n<p>It even works in Opera! Note that the <code>background-size<\/code> must be set to <code>auto<\/code> in order to override the default style in the polyfill.  :-)<\/p>\n<p><a href=\"https:\/\/www.useragentman.com\/examples\/progress\/\" class=\"exampleLink\">See the above CSS in action in a &#8220;clean room&#8221; page<\/a><\/p>\n<h2>That&#8217;s Too Basic! I Want Fancy-Pants&trade; Progress Bars<\/h2>\n<p>So, now that you know the basics, let&#8217;s take a look at some more complicated and interesting progress bars:<\/p>\n<h3>Two Image Effect<\/h3>\n<p>This progress bar uses two versions of the same image (one grey-scale, one color) to differentiate between the progress bar background and value: <\/p>\n<div class=\"example\">\n<progress class=\"example2\" min=\"0\" max=\"100\" value=\"60\"><\/progress>\n<\/div>\n<p><a href=\"https:\/\/www.useragentman.com\/examples\/progress\/uam.html\" class=\"exampleLink\">See the above example in action in a &#8220;clean room&#8221; page<\/a><\/p>\n<p>Unfortunately, this example doesn&#8217;t work in Opera and IE10, since at this time one cannot style the progress bar value with an image in those browsers.<\/p>\n<h3>Gradients<\/h3>\n<p>Note that  not only can you use <code>background-color<\/code>s and <code>-image<\/code>s, but also use the variety of gradients that are available for developers today in supported browsers (this does <strong>not<\/strong> include IE9 and lower).  To prove this, I took Chris Croyer beautiful <code>&lt;div&gt;<\/code> style progress bars from his <a href=\"http:\/\/css-tricks.com\/css3-progress-bars\/\">blog post on CSS3 based progress bars<\/a> and HTML5-ified&trade; them here:<\/p>\n<div class=\"example\">\n<progress class=\"example3\" min=\"0\" max=\"100\" value=\"60\"><\/progress>\n<\/div>\n<div class=\"example\">\n<progress class=\"example4\" min=\"0\" max=\"100\" value=\"60\"><\/progress>\n<\/div>\n<p>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):<\/p>\n<blockquote class=\"code shortened\">\n<pre>\r\n\/*\r\n * Gradient Shadow\r\n *\/\r\n\r\n\/* All HTML5 progress enabled browsers *\/\r\nprogress.example3 {\r\n\r\n\t\/* Turns off styling - not usually needed, but good to know. *\/\r\n\tappearance: none;\r\n\t-moz-appearance: none;\r\n\t-webkit-appearance: none;\r\n\t\/* gets rid of default border in Firefox and Opera. *\/\r\n\tborder: solid #cccccc 5px;\r\n\tborder-radius: 10px;\r\n\t\/* Dimensions *\/\r\n\twidth: 238px;\r\n\theight: 45px;\r\n}\r\n\r\n\/* Polyfill *\/\r\nprogress.example3[role]:after {\r\n\tbackground-image: none; \/* removes default background from polyfill *\/\r\n}\r\n\r\n\/*\r\n * Background of the progress bar background\r\n *\/\r\n\r\n\/* Firefox and Polyfill *\/\r\nprogress.example3 {\r\n\tbackground: #cccccc !important; \/* !important only needed in polyfill *\/\r\n}\r\n\r\n\/* Chrome *\/\r\nprogress.example3::-webkit-progress-bar {\r\n\tbackground: #cccccc;\r\n}\r\n\r\n\/*\r\n * Background of the progress bar value\r\n *\/\r\n\r\n\/* Firefox *\/\r\nprogress.example3::-moz-progress-bar {\r\n\tborder-radius: 5px;\r\n\tbackground-image: -moz-linear-gradient(\r\n\t\tcenter bottom,\r\n\t\trgb(43,194,83) 37%,\r\n\t\trgb(84,240,84) 69%\r\n\t);\r\n}\r\n\r\n\/* Chrome *\/\r\nprogress.example3::-webkit-progress-value {\r\n\tborder-radius: 5px;\r\n\tbackground-image: -webkit-gradient(\r\n\t\tlinear,\r\n\t\tleft bottom,\r\n\t\tleft top,\r\n\t\tcolor-stop(0, rgb(43,194,83)),\r\n\t\tcolor-stop(1, rgb(84,240,84))\r\n\t);\r\n\tbackground-image: -webkit-linear-gradient(\r\n\t\tcenter bottom,\r\n\t\trgb(43,194,83) 37%,\r\n\t\trgb(84,240,84) 69%\r\n\t);\r\n}\r\n\r\n\/* Polyfill *\/\r\nprogress.example3[aria-valuenow]:before {\r\n\tborder-radius: 5px;\r\n\tbackground-image: -moz-linear-gradient(\r\n\t\tcenter bottom,\r\n\t\trgb(43,194,83) 37%,\r\n\t\trgb(84,240,84) 69%\r\n\t);\r\n\tbackground-image: -ms-linear-gradient(\r\n\t\tcenter bottom,\r\n\t\trgb(43,194,83) 37%,\r\n\t\trgb(84,240,84) 69%\r\n\t);\r\n\tbackground-image: -o-linear-gradient(\r\n\t\tcenter bottom,\r\n\t\trgb(43,194,83) 37%,\r\n\t\trgb(84,240,84) 69%\r\n\t);\r\n\t\r\n}\r\n<\/pre>\n<\/blockquote>\n<p>This example doesn&#8217;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&#8217;t style the progress bar at all).  Also, note that I did not use the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms532997%28v=vs.85%29.aspx\"><code>Gradient<\/code> filter<\/a> to polyfill CSS3 gradients in IE6-9.  This is because Visual Filters don&#8217;t work in CSS3 pseudo-elements like <code>:before<\/code> or <code>:after<\/code>.  Oh well.   <\/p>\n<p><a href=\"https:\/\/www.useragentman.com\/examples\/progress\/striping.html\" class=\"exampleLink\">See the above CSS in action in a \u201cclean room\u201d page<\/a><\/p>\n<h3>Monkeys!<\/h3>\n<p>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).  <\/p>\n\r\n<div class=\"example\">\r\n<progress class=\"monkey\" min=\"0\" max=\"100\" value=\"60\"><\/progress><div class=\"after\"><\/div>\r\n<\/div>\r\n<p>Apologies to the great <a href=\"http:\/\/banksy.co.uk\/\">Banksy<\/a> &mdash; it&#8217;s not <a href=\"http:\/\/www.guyhepner.com\/index.php?url=images\/get\/509x397\/3087\/banksy-paintings-laugh-now-but-one-day-we-ll-be-in-charge.jpg\">his monkey<\/a> but one grabbed from <a href=\"http:\/\/www.animatedgif.net\/clockscounters\/clockscounters3.shtml\">this Animated GIF site<\/a> and converted into a <a href=\"http:\/\/www.alistapart.com\/articles\/sprites\">CSS sprite<\/a> using <a href=\"http:\/\/blog.somepixels.net\/\">Andr\u00e9 Gil&#8217;s<\/a> super-cool <a href=\"http:\/\/labs.andregil.net\/Gif2TileSet\/Gif2TileSet.html\">Gif2TileSet tool<\/a>.  I took this sprite and animated the monkey using blitting whenever the progress bar changes values (thanks to my friend and colleague <a href=\"http:\/\/noel.tibbles.ca\/\">Noel Tibbles<\/a> for turning me on to this technique).<\/p>\n<p>Note the HTML has an extra <code>&lt;div&gt;<\/code> tag so the monkey has a place to live:<\/p>\n<blockquote class=\"code\">\n<pre>\r\n&lt;progress class=\"monkey\" min=\"0\" max=\"100\" value=\"60\"&gt;&lt;\/progress&gt;\r\n&lt;div class=\"after\"&gt;&lt;\/div&gt;\r\n<\/pre>\n<\/blockquote>\n<p><strong>I wish that I could have used <code>:after<\/code> (or <code>::after<\/code>) rules<\/strong> instead, but these pseudo-elements <strong>don&#8217;t work with the <code>progress<\/code> tags in <em>any<\/em> browser that doesn&#8217;t use the polyfill<\/strong>.  And no, <code>:before<\/code> doesn&#8217;t work either.  I have no idea why it doesn&#8217;t work, but it&#8217;s a shame &mdash; using them would be perfect to get rid of the extra markup.<\/p>\n<p>The CSS that makes the monkey animate when the progress bar changes values is here:<\/p>\n<blockquote class=\"code\">\n<pre>\r\nprogress.monkey[value=\"0\"] +  .after{\r\n\tbackground: url('\/blog\/wp-content\/uploads\/2011\/12\/monkeyBlit.gif');\r\n} \r\n\r\nprogress.monkey[value^=\"1\"] +  .after {\r\n\tbackground: url('\/blog\/wp-content\/uploads\/2011\/12\/monkeyBlit.gif') 0  -77px ;\r\n}\r\n\r\nprogress.monkey[value^=\"2\"] +  .after {\r\n\tbackground: url('\/blog\/wp-content\/uploads\/2011\/12\/monkeyBlit.gif') 0  -154px ;\r\n}\r\n\r\nprogress.monkey[value^=\"3\"] +  .after,\r\nprogress.monkey[value=\"100\"] +  .after  {\r\n\tbackground: url('\/blog\/wp-content\/uploads\/2011\/12\/monkeyBlit.gif') 0  -231px !important ;\r\n}\r\n\r\nprogress.monkey[value^=\"4\"] +  .after {\r\n\tbackground: url('\/blog\/wp-content\/uploads\/2011\/12\/monkeyBlit.gif') 0  -308px ;\r\n}\r\n\r\nprogress.monkey[value^=\"5\"] +  .after {\r\n\tbackground: url('\/blog\/wp-content\/uploads\/2011\/12\/monkeyBlit.gif') 0  -385px ;\r\n}\r\n\r\nprogress.monkey[value^=\"6\"] +  .after {\r\n\tbackground: url('\/blog\/wp-content\/uploads\/2011\/12\/monkeyBlit.gif') 0  -462px ;\r\n}\r\n\r\nprogress.monkey[value^=\"7\"] +  .after {\r\n\tbackground: url('\/blog\/wp-content\/uploads\/2011\/12\/monkeyBlit.gif') 0  -539px ;\r\n}\r\n\r\nprogress.monkey[value^=\"8\"] +  .after {\r\n\tbackground: url('\/blog\/wp-content\/uploads\/2011\/12\/monkeyBlit.gif') 0  -616px ;\r\n}\r\n\r\nprogress.monkey[value^=\"9\"] +  .after {\r\n\tbackground: url('\/blog\/wp-content\/uploads\/2011\/12\/monkeyBlit.gif') 0  -693px ;\r\n}\r\n<\/pre>\n<\/blockquote>\n<p>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 &#8211; 100 and the progress bar increments by 10.  They monkeys don&#8217;t appear in IE8 and under because of it&#8217;s lack of support of the ^= attribute selector (but it works well in IE9).<\/p>\n<p>Note that <strong>this would be much easier if CSS allowed us to combine the CSS3 <code>calc()<\/code> and <code>attr()<\/code> attributes together<\/strong> like <a href=\"http:\/\/lea.verou.me\/2010\/09\/on-attr-and-calc\/\">Lea Verou dreams about in one of her blog posts<\/a>:<\/p>\n<blockquote class=\"code\">\n<pre>\r\n\/*\r\n * Don't try this - it doesn't work in any browser, but it would be nice if it did.\r\n *\/\r\n\r\nprogress.monkey::after {\r\n   background-image: url('\/blog\/wp-content\/uploads\/2011\/12\/monkeyBlit.gif');\r\n   background-position-x: 0;\r\n   background-position-y: calc(-77 * attr(value), 'px');\r\n}\r\n<\/pre>\n<\/blockquote>\n<p>Hopefully this will come to pass in the future.<\/p>\n<p><a href=\"https:\/\/www.useragentman.com\/examples\/progress\/blit.html\" class=\"exampleLink\">See the above CSS in action in a \u201cclean room\u201d page<\/a><\/p>\n<h3>Speedometer<\/h3>\n<p>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 <code>transform<\/code>) <\/p>\n\r\n<div class=\"example speedometer\">\r\n<div id=\"progressContainer\">\r\n  <progress id=\"rot\" class=\"example_r\" min=\"0\" max=\"100\" value=\"60\"><\/progress>\r\n  <div data-arrow-for=\"rot\" class=\"arrow\"><img decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/2012\/01\/hand.png\" \/><\/div>\r\n<\/div>\r\n<\/div>\r\n<p>The CSS is similar to the monkey example in that I add an extra <code>&lt;div&gt;<\/code> after the progress tag, except that it has an image of a pointer inside of it.<\/p>\n<blockquote class=\"code\">\n<pre>\r\n&lt;div id=\"progressContainer\"&gt;\r\n  &lt;progress id=\"rot\" class=\"example_r\" min=\"0\" max=\"100\" value=\"60\"&gt;&lt;\/progress&gt;\r\n  &lt;div data-arrow-for=\"rot\" class=\"arrow\"&gt;&lt;img src=\"\/blog\/wp-content\/uploads\/2012\/01\/hand.png\" \/&gt;&lt;\/div&gt;\r\n&lt;\/div&gt;\r\n<\/pre>\n<\/blockquote>\n<p>I wrapped both these tags inside a relatively positioned container <code>&lt;div&gt;<\/code>.  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 <code>border-radius<\/code> and part of a <a href=\"http:\/\/www.flickr.com\/photos\/listener42\/4991330345\/\">photo from Flickr user &#8216;listener42&#8217;<\/a> &#8230;<\/p>\n<blockquote class=\"code\">\n<pre>\r\nprogress.example_r {\r\n\r\n\t\/* gets rid of default border in Firefox and Opera. *\/\r\n\tborder: solid 1px black;\r\n\tdisplay: inline-block;\r\n\t\r\n\t\/* Produces the semi-circle *\/\r\n\t<span class=\"hilite\">border-radius: 238px 238px 0 0;<\/span>\r\n\r\n\t\/* Dimensions *\/\r\n\twidth: 238px;\r\n\theight: 126px;\r\n\tpadding: 0;\r\n\r\n        \/* IE needs this to hide the native progress bar value *\/\r\n        color: transparent;\r\n}\r\n<\/pre>\n<\/blockquote>\n<p>&#8230; and make the arrow rotate as the progress bar increments by using CSS transforms: <\/p>\n<blockquote class=\"code shortened\">\n<pre>\r\nprogress.example_r[value=\"0\"] + .arrow {\r\n\t-moz-transform: rotate(270deg);\r\n\t-webkit-transform: rotate(270deg);\r\n\t-o-transform: rotate(270deg);\r\n\t-ms-transform: rotate(270deg);\r\n}\r\n\r\nprogress.example_r[value^=\"1\"]:not([value=\"1\"]):not([value=\"100\"]) + .arrow {\r\n\t-moz-transform: rotate(288deg);\r\n\t-webkit-transform: rotate(288deg);\r\n\t-o-transform: rotate(288deg);\r\n\t-ms-transform: rotate(288deg);\r\n}\r\n\r\nprogress.example_r[value^=\"2\"]:not([value=\"2\"]) + .arrow {\r\n\t-moz-transform: rotate(306deg);\r\n\t-webkit-transform: rotate(306deg);\r\n\t-o-transform: rotate(306deg);\r\n\t-ms-transform: rotate(306deg);\r\n}\r\n\r\nprogress.example_r[value^=\"3\"]:not([value=\"3\"]) + .arrow {\r\n\t-moz-transform: rotate(324deg);\r\n\t-webkit-transform: rotate(324deg);\r\n\t-o-transform: rotate(324deg);\r\n\t-ms-transform: rotate(324deg);\r\n}\r\n\r\nprogress.example_r[value^=\"4\"]:not([value=\"4\"]) + .arrow {\r\n\t-moz-transform: rotate(342deg);\r\n\t-webkit-transform: rotate(342deg);\r\n\t-o-transform: rotate(342deg);\r\n\t-ms-transform: rotate(342deg);\r\n}\r\n\r\nprogress.example_r[value^=\"5\"]:not([value=\"5\"]) + .arrow {\r\n\t-moz-transform: rotate(360deg);\r\n\t-webkit-transform: rotate(360deg);\r\n\t-o-transform: rotate(360deg);\r\n\t-ms-transform: rotate(360deg);\r\n}\r\n\r\nprogress.example_r[value^=\"6\"]:not([value=\"6\"]) + .arrow {\r\n\t-moz-transform: rotate(378deg);\r\n\t-webkit-transform: rotate(378deg);\r\n\t-o-transform: rotate(378deg);\r\n\t-ms-transform: rotate(378deg);\r\n}\r\n\r\nprogress.example_r[value^=\"7\"]:not([value=\"7\"]) + .arrow {\r\n\t-moz-transform: rotate(396deg);\r\n\t-webkit-transform: rotate(396deg);\r\n\t-o-transform: rotate(396deg);\r\n\t-ms-transform: rotate(396deg);\r\n}\r\n\r\nprogress.example_r[value^=\"8\"]:not([value=\"8\"]) + .arrow {\r\n\t-moz-transform: rotate(414deg);\r\n\t-webkit-transform: rotate(414deg);\r\n\t-o-transform: rotate(414deg);\r\n\t-ms-transform: rotate(414deg);\r\n}\r\n\r\nprogress.example_r[value^=\"9\"]:not([value=\"9\"]) + .arrow {\r\n\t-moz-transform: rotate(432deg);\r\n\t-webkit-transform: rotate(432deg);\r\n\t-o-transform: rotate(432deg);\r\n\t-ms-transform: rotate(432deg);\r\n}\r\n\r\nprogress.example_r[value=\"100\"] + .arrow {\r\n\t-moz-transform: rotate(450deg);\r\n\t-webkit-transform: rotate(450deg);\r\n\t-o-transform: rotate(450deg);\r\n\t-ms-transform: rotate(450deg);\r\n}\r\n<\/pre>\n<\/blockquote>\n<p>Again, the CSS would be much smaller in size if I could use <code>calc()<\/code> and <code>attr()<\/code> together, but again, oh well.   Furthermore, that this example doesn&#8217;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&#8217;s color to <code>transparent<\/code> a thin line can be seen where the end of the progresss bar used to be.  Ugh&#8230; :-(<\/p>\n<p><a href=\"https:\/\/www.useragentman.com\/examples\/progress\/rotate.html\" class=\"exampleLink\">See the above CSS in action in a \u201cclean room\u201d page<\/a><\/p>\n<h2>Summary of Gotchas<\/h2>\n<p>As mentioned before, there are a few annoyances I have found with they way the browsers have implemented HTML5 progress bars:<\/p>\n<ol>\n<li>You cannot use <code>:before<\/code>\/<code>::before<\/code> or <code>:after<\/code>\/<code>::after<\/code> pseudo-elements on the <code>progress<\/code> element.  Why this is not allowed is unclear to me, and I hope this is allowed in the future.<\/li>\n<li>Safari 5.0 and lower cannot use the polyfill, so you should always use the fallback HTML inside the <code>&lt;progress&gt;<\/code> tag.<\/li>\n<li>It seems like it is impossible to change Opera&#8217;s progress bar value style to anything besides green.<\/li>\n<li>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.<\/li>\n<li>There is a <strong>small bug in the polyfill<\/strong> when applying borders to the progress bar.  I have <a href=\"https:\/\/github.com\/zoltan-dulac\/HTML5-Progress-polyfill\">a fix<\/a> that has been <a href=\"https:\/\/github.com\/LeaVerou\/HTML5-Progress-polyfill\/pull\/6\">submitted as a pull request<\/a> and I assume being reviewed, but in the meantime, you can <a href=\"https:\/\/github.com\/zoltan-dulac\/HTML5-Progress-polyfill\">get my forked version of the polyfill (with the bug fix) on GitHub<\/a>.<\/li>\n<\/ol>\n<h2>Help Me Keep This Page Up-To-Date!<\/h2>\n<p>If you find out more information about the HTML5 <code>progress<\/code> tag, I&#8217;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. :-)<\/p>\n<p><script src=\"\/shared\/js\/lea.verou.me\/progressPolyfill\/progress-polyfill.js\"><\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/www.useragentman.com\/blog\/wp-content\/uploads\/2012\/01\/intro.png\" \/>  As a web application developer,<strong> progress bars are great when you want to show the user that some action is happening,<\/strong> especially when it can take a long time.  Creating them is easy with the HTML5 <code>&lt;progress&gt;<\/code> tag.  This article will discuss <strong>how this tag is rendered by default<\/strong> in all operating systems and browsers and how to <strong>style the <code>progress<\/code> tag with CSS<\/strong>, even in browsers that don&#8217;t officially support the it.  It will also show some <strong>interesting examples using advanced CSS3 techniques.<\/strong><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[38,50,125,8,35,119,143],"tags":[],"class_list":["post-4016","post","type-post","status-publish","format-standard","hentry","category-css3","category-forms","category-gradients","category-html","category-html5","category-polyfills","category-progress"],"_links":{"self":[{"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/posts\/4016","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/comments?post=4016"}],"version-history":[{"count":241,"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/posts\/4016\/revisions"}],"predecessor-version":[{"id":4309,"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/posts\/4016\/revisions\/4309"}],"wp:attachment":[{"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/media?parent=4016"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/categories?post=4016"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.useragentman.com\/blog\/wp-json\/wp\/v2\/tags?post=4016"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}