CSS

How to create a CSS3 progress bar

The progress bar has been used on the web ever since we realized that not everything would load instantly for everyone. These bars serve to notify the user about the progress of a specific task in your website, such as uploading, downloading, loading an app etc.

It used to be impossible to create a progress bar animation without the use of JavaScript but thanks to CSS3 we’re now able to perform animations, add gradients and some multi-color element inside a div. In fact HTML5 has also a special progress bar element created exactly for this purpose.

When you’re done with this tutorial you’ll know how to make a flat design animated progress bar using pure css: no flash, no images and no JavaScript.

Let’s get started…

The markup

For our markup we will have a .container div which will hold our progress bar followed by the .title div for our title.

Next, we will be adding the .bar div to hold the both the unfilled and filled section of our bar. Finally, we will be adding our .bar-unfill and .bar-fill span tags inside it.

<div class="container">
    <div class="title plain">Plain</div>
    <div class="bar">
        <span class="bar-unfill">
            <span class="bar-fill"></span>
        </span>
     </div>
</div>

Plain progress bar CSS

The .container class will have the exact width of 30% to make our progress bar responsive. We will also put some simple border radius on our .title class  on both top and bottom left to create a plain and simple flat design.

.container {
    width:30%;
    margin:0 auto
}

.title {
    background:#545965;
    color:#fff;
    padding:15px;
    float:left;
    position:relative;
    -webkit-border-top-left-radius:5px;
    -webkit-border-bottom-left-radius:5px;
    -moz-border-radius-topleft:5px;
    -moz-border-radius-bottomleft:5px;
    border-top-left-radius:5px;
    border-bottom-left-radius:5px
}

Now let’s style the unfilled section first and give it a background of plain white.

.bar-unfill {
    height:15px;
    display:block;
    background:#fff;
    width:100%;
    border-radius:8px
}

Next, we will style our bar class and give it a width of 100%. This will hold both the filled and unfilled section. Then, on our .bar-fill class we will give it a width of 0% as a starting width. We will also add CSS3 transition to make our animation smooth. Finally, we will add our CSS3 animation defining the name of our animation, the duration and the animation-iteration-count property.

.bar-fill {
    height:15px;
    display:block;
    background:#45c9a5;
    width:0;
    border-radius:8px;
    -webkit-transition:width .8s ease;
    -moz-transition:width .8s ease;
    transition:width .8s ease;
    -webkit-animation:progressbar 7s infinite;
    animation:progressbar 7s infinite
}

To make this animate, we will use CSS3 @keyframe rule to set the width from 0 to 100%. You can also customize the set up below on your own preferred set up.

/* Chrome, Safari, Opera */
@-webkit-keyframes progressbar { 
    from {
        width:0
    }
    to {
        width:100%
    }
}
/* Standard syntax */
@keyframes progressbar {
    from {
        width:0
    }
    to {
        width:100%
    }
}

Striped progress bar CSS

For a striped progress bar, we will rename our .bar-fill class to .bar-fill-stripes. We will use the linear gradient and declare the colors of it via background-image property. The rest of the CSS3 animation and transition will remain the same. See the code below.

.bar-fill-stripes {
    height:15px;
    display:block;
    background:#e74c3c;
    width:0;
    border-radius:8px;
    background-image:linear-gradient(-45deg,rgba(255,255,255,.2) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.2) 50%,rgba(255,255,255,.2) 75%,transparent 75%,transparent);
    -webkit-transition:width .8s ease;
    -moz-transition:width .8s ease;
    transition:width .8s ease;
    -webkit-animation:progressbar 7s infinite;
    animation:progressbar 7s infinite
}

Progress Bar with Tracker

For this part of our tutorial, we’re going to create a tracker for our progress bar. So we will adjust our markup a bit, as well our CSS. Check out the markup below.

<div class="container">
    <div class="title">Tracker</div>
    <div class="bar">
        <span class="bar-unfill">
            <span class="bar-fill-tracker"></span>
            <span class="track-wrap">
                <span class="track"></span>
            </span>
        </span>
    </div>
</div>

As you can see we’ve added the span class .track wrap and .track inside the .bar-unfill div. This will hold our circle tracker and then animate it using another @keyframe rule. Let’s write the style for our .track-wrap and .track classes.

.track-wrap {
    position:relative;
    top:-18px;
    -webkit-animation:progressbar2 7s infinite;
    animation:progressbar2 7s infinite
}

.track {
    height:20px;
    display:block;
    background:#e74c3c;
    width:20px;
    border-radius:10px;
    position:relative;
    left:-12px
}

/* Chrome, Safari, Opera */

@-webkit-keyframes progressbar2 {
    from {
        left:0
    }
    to {
        left:100%
    }
}

/* Standard syntax */

@keyframes progressbar2 {
    from {
        left:0
    }
    to {
        left:100%
    }
}

As you can see above, I set up the position of the .track-wrap class to relative to the top -18px, and then set up an animation property. Next, I set up the track class which is the actual tracker and set the border radius to 10px and left to -12px. Another thing that I’ve added is the new animation using the @keyframe rule named progressbar2.

HTML5 Progress Bar

In our previous demos we’ve used divs to create a progress bar; but this time we’re going to look on how to use the HTML5 progress bar.

The Basic Markup

The HTML5 progress bar element can be added with <progress> tag. Inside this tag, we can set up the progress value within the value, min, and max attributes. Check out the basic markup below.

<progress value="50" max="100"></progress>

Now to align this with our flat design we can incorporate this with our markup above. See codes below. <div class=”container”>

<div class="title html5">HTML5</div>
<div class="bar">
    <span class="bar-unfill">
        <progress value="50" max="100"></progress>
    </span>
</div>

There is nothing special here. We just changed our span class bar-fill to the progress bar tag . Now let’s try to style our HTML5 progress bar.

progress, progress::-webkit-progress-bar{
    height:15px;
    display:block;
    background-color:#8e44ad;
    width:0;
    -webkit-border-radius: 8px;
    border-radius:8px;
    color: #fff;
    -webkit-transition:width .8s ease;
    -moz-transition:width .8s ease;
    transition:width .8s ease;
    -webkit-animation:progressbar 7s infinite;
    animation:progressbar 7s infinite
}

progress::-moz-progress-bar {
    height:15px;
    display:block;
    background-color:#8e44ad;
    width:0;
    -webkit-border-radius: 8px;
    border-radius:8px;
    color: #fff;
    -webkit-transition:width .8s ease;
    -moz-transition:width .8s ease;
    transition:width .8s ease;
    -webkit-animation:progressbar 7s infinite;
    animation:progressbar 7s infinite
}

To change the style of progress bar we need to add some Webkit and Mozilla pseudo classes that were intentionally made for both Chrome and Mozilla.

progress::-webkit-progress-bar {
    /* style rules for Chrome */
}

progress::-moz-progress-bar {
    /* style rules for Firefox*/
}

Now to finalize our HTML5 progress bar design, I’ve come up with the following CSS.

progress::-webkit-progress-bar{
    height:15px;
    display:block;
    background-color:#8e44ad;
    width:0;
    -webkit-border-radius: 8px;
    border-radius:8px;
    color: #fff;
    -webkit-transition:width .8s ease;
    -moz-transition:width .8s ease;
    transition:width .8s ease;
    -webkit-animation:progressbar 7s infinite;
    animation:progressbar 7s infinite
}

progress::-moz-progress-bar {
    height:15px;
    display:block;
    background-color:#8e44ad;
    width:0;
    -webkit-border-radius: 8px;
    border-radius:8px;
    color: #fff;
    -webkit-transition:width .8s ease;
    -moz-transition:width .8s ease;
    transition:width .8s ease;
    -webkit-animation:progressbar 7s infinite;
    animation:progressbar 7s infinite
}

Now, using our previous @keyframe rule that we’ve set up on our first example, you’ll get similar results, like in the image below.

Note: Please check out this page regarding the support for HTML5 progress bar.

Sam Norton is a web designer and a front web developer with over 2 years of experience in the industry. Have a passion for designing detailed, creative and modern websites & graphics. He spend most of his time practically every day, experimenting with HTML, CSS and Wordpress. More articles by Sam Norton
  • +1 for using the true CSS3 animations and not the jQuery/javascript based one’s, which are very choppy

  • Hey sam ,
    Thank you for this valuable post. I tried to implement all the examples given by you and all worked well except progress bar with tracker. There are some errors when i tried to develop this.

Home CSS Deals HTML HTML5 Java JavaScript jQuery Miscellaneous Mobile MySQL News PHP Resources Security Snippet Tools Tutorial Web Development Web Services WordPress