A simple HTML5 Progress bar

Today I fell in love with the HTML5 <progress> bar. With this element, I can display the progress of a task using HTML and CSS. Here is the markup:

<div class="Progress">
    <span class="Progress-label">Average: <strong>80%</strong></span>
    <progress max="100" value="80" class="Progress-main">
        <div class="Progress-bar" role="presentation">
            <span class="Progress-value" style="width: 80%;"> </span>

The progress bar

The progress element requires a start tag and an end tag, which means it can contain fallback content. What you see inside the progress element will only be read when <progress> isn't supported. In this example, I've built a fallback progress bar using CSS, so both possible outcomes look the same.

The progress element has two attributes:

  • max indicates the completed value
  • value indicates the current value of the progress bar. If this value exists then the progress bar is considered to be determinate, otherwise it's considered indeterminate.

To make the progress bar more accessible, I have given it a text label. So, if the bar cannot be seen by assistive technology, the text above it describes the value just fine. Therefore, the content inside <progress> is not really necessary; it's just for presentation. That's why I've added aria role="presentation" to the div called 'Progress-bar'. This tells assistive technology to ignore it.


First of all, I styled the progress element. It has few styles like height, width and margin, all of which behave as expected. However, background-color acts strangely to me. It doesn't actually change the colour of anything, but it seems to trigger a canvas for setting colours via all the vendor pseudo elements. Essentially, the background-color needs to be there to allow pseudo elements to style it, but the colour value doesn't appear to get read—the value could be anything. Interesting.

/*Variables for colours*/
$progressBarColour: #F2F2F2;
$progressValueColour: #17BAB3;
/*The progress element*/
.Progress-main {
    background-color: $progressBarColour; /*This could be any colour*/
    width: 100%;
    height: 0.3em;
    margin-top: 0.75em;

This is where the fun begins (or ends) because different browsers require different sets of pseudo elements to style the progress bar.

/*For firefox*/
.Progress-main::-moz-progress-bar { 
    background: $progressValueColour;
/*For webkit browsers*/
.Progress-main::-webkit-progress-bar {
    background: $progressBarColour;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2) inset;
.Progress-main::-webkit-progress-value {
    background: $progressValueColour;
/*For IE*/
.Progress-main::-ms-fill { 
    background: $progressValueColour;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2) inset;

For the finishing touches, I styled the fallback content to make it look the same as the progress bar. So if browsers don't support the progress element, the fallback looks pretty much the same.

.Progress-bar {
    margin-top: 0.95em;
    background-color: $progressBarColour;
    height: 0.3em;
.Progress-value {
    background-color: $progressValueColour;
    display: block;
    height: 0.3em;

See the Pen EPbKbX by Lottejackson (@lottejackson) on CodePen.