Create Your Own CSS3 Progress Bars

CSS3 has heralded nothing short of a revolution in website functionality and design. CSS3 allows web developers to create dynamic, flexible and easily modifiable web content, while bypassing cumbersome images and JavaScript plug-ins. This tutorial will show you how to code an impressive progress bar from scratch, using pure CSS3 styles; no images, no JS.

Before we start, for the purposes of this demo I recommend you install the latest version of Firefox, Chrome or Safari. The CSS3 properties I use below are not currently supported by either Internet Explorer or Opera.

Our tutorial will create progress bar effects similar to those depicted in the following image:

Step One: HTML

The HTML for these progress bars is deceptively simple. Start by creating a <div>element with a class of “progress”. Within this element, set up a child <span>element to contain the bar’s current progress area. The code should look like this:

<div class="progress">
   <span></span>
</div>

Once the markup is in place, you are ready to move to the fun part; getting stuck into the CSS3! The visual effects on the progress bar each need a separate CSS class. For example, the gradient effect shown in the image above has the class of “gradient”; the striped effect is represented by the “stripe” class. The same applies to the animate and gloss effects.

Step Two: The Basic CSS

Coding the basic CSS progress bar is very simple. Essentially you have to create two different elements; the “progress” class itself and a child <span> element. Similar rules apply to setting up the styles for the other classes. Once you’ve established the basics, you code the required effects to be applied to the child <span> element. Your base CSS code should look something like this:

.progress {
  margin: 5px 0 3px;
  border: 6px solid #333;
  background: #333;
  overflow: hidden;
  border-radius: 50px;
  -moz-border-radius: 50px;
  -webkit-border-radius: 50px;
  box-shadow: 1px 1px 1px #777;
  -moz-box-shadow: 1px 1px 1px #777;
  -webkit-box-shadow: 1px 1px 1px #777;
}
.progress > span {
  display: block;
  height: 20px;
  width: 20%;
  border-radius: 5px;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
}

Colors, margins, element height and other properties can be modified to suit the layout of your own website.

Step Three: The Gradient Effect

Rather than using the CSS3 gradient effect, I find it more effective to utilise the box-shadow property to create the required effect. The gradient property will often do more than simply create a gradient, so is better utilised when coding more complex effects. Another problem is that Internet Explorer 8 does not support many of the more complicated CSS3 styles, including the gradient background. As a way round this, you will notice in the code below that I have applied the filter property as a fallback. At the very least, viewers of your website using IE8 will see some sort of gradient effect, rather than a plain color.

The code to create the gradient effect progress bar is shown below.


.gradient > span {
  box-shadow: 0 5px 5px rgba(255,255,255,0.6) inset, 0 -5px 7px rgba(0, 0, 0, 0.4) inset;
  -moz-box-shadow: 0 5px 5px rgba(255,255,255,0.6) inset, 0 -5px 7px rgba(0, 0, 0, 0.4) inset;
  -webkit-box-shadow: 0 5px 5px rgba(255,255,255,0.6) inset, 0 -5px 7px rgba(0, 0, 0, 0.4) inset;
  filter: progid:DXImageTransform.Microsoft.gradient(
    startColorstr='#33ffffff',
    endColorstr='#33000000',
    GradientType=0 );
}

Step Four: The Gloss Effect

The CSS3 background gradient property can be used effectively to create a glossy progress bar. What this does is impose a partially transparent gloss effect on top of the progress bar itself, meaning you can use it to apply a gloss effect on any underlying color. As when creating the gradient effect, I created a “gloss” class to determine the required styles. Here is the CSS:

.gloss > span {
  background-image: -moz-linear-gradient(top,
    rgba(255,255,255,0.2) 0%,
    rgba(255,255,255,0.1) 45%,
    rgba(0,0,0,0.2) 55%,
    rgba(0,0,0,0.1) 100%);
  background-image: -webkit-gradient(linear, left top, left bottom,
    color-stop(0%,rgba(255,255,255,0.2)),
    color-stop(45%,rgba(255,255,255,0.1)),
    color-stop(55%,rgba(0,0,0,0.2)),
    color-stop(100%,rgba(0,0,0,0.1)));
  background-image: -webkit-linear-gradient(top,
    rgba(255,255,255,0.5) 0%,
    rgba(255,255,255,0.1) 45%,
    rgba(0,0,0,0.2) 55%,
    rgba(0,0,0,0.1) 100%);
  background-image: -o-linear-gradient(top,
    rgba(255,255,255,0.2) 0%,
    rgba(255,255,255,0.1) 45%,
    rgba(0,0,0,0.2) 55%,
    rgba(0,0,0,0.1) 100%);
  background-image: -ms-linear-gradient(top,
    rgba(255,255,255,0.2) 0%,
    rgba(255,255,255,0.1) 45%,
    rgba(0,0,0,0.2) 55%,
    rgba(0,0,0,0.1) 100%);
  background-image: linear-gradient(to bottom,
    rgba(255,255,255,0.2) 0%,
    rgba(255,255,255,0.1) 45%,
    rgba(0,0,0,0.2) 55%,
    rgba(0,0,0,0.1) 100%);
}

Step Five: Applying the Stripes

By now you should be familiar with the basic process. To create the striped effect, set up a “stripe” class using the following code. This class works the same as the gloss, in applying a semi-transparent finish to the progress bar that can be adapted to any color as required.

.stripe > span {
  background-size: 30px 30px;
  background-image: -moz-linear-gradient(-45deg,
    rgba(255,255,255,0.15) 0%,
    rgba(255,255,255,0.15) 25%,
    rgba(255,255,255,0) 25%,
    rgba(255,255,255,0) 50%,
    rgba(255,255,255,0.15) 50%,
    rgba(255,255,255,0.15) 75%,
    rgba(255,255,255,0) 75%,
    rgba(255,255,255,0) 100%);
  background-image: -webkit-gradient(linear, left top, right bottom,
    color-stop(0%,rgba(255,255,255,0.2)),
    color-stop(25%,rgba(255,255,255,0.2)),
    color-stop(25%,rgba(255,255,255,0)),
    color-stop(50%,rgba(255,255,255,0)),
    color-stop(50%,rgba(255,255,255,0.2)),
    color-stop(75%,rgba(255,255,255,0.2)),
    color-stop(75%,rgba(255,255,255,0)),
    color-stop(100%,rgba(255,255,255,0)));
  background-image: -webkit-linear-gradient(-45deg,
    rgba(255,255,255,0.3) 0%,
    rgba(255,255,255,0.3) 25%,
    rgba(255,255,255,0) 25%,
    rgba(255,255,255,0) 50%,
    rgba(255,255,255,0.3) 50%,
    rgba(255,255,255,0.3) 75%,
    rgba(255,255,255,0) 75%,
    rgba(255,255,255,0) 100%);
  background-image: -o-linear-gradient(-45deg,
    rgba(255,255,255,0.15) 0%,
    rgba(255,255,255,0.15) 25%,
    rgba(255,255,255,0) 25%,
    rgba(255,255,255,0) 50%,
    rgba(255,255,255,0.15) 50%,
    rgba(255,255,255,0.15) 75%,
    rgba(255,255,255,0) 75%,
    rgba(255,255,255,0) 100%);
  background-image: -ms-linear-gradient(-45deg,
    rgba(255,255,255,0.15) 0%,
    rgba(255,255,255,0.15) 25%,
    rgba(255,255,255,0) 25%,
    rgba(255,255,255,0) 50%,
    rgba(255,255,255,0.15) 50%,
    rgba(255,255,255,0.15) 75%,
    rgba(255,255,255,0) 75%,
    rgba(255,255,255,0) 100%);
  background-image: linear-gradient(135deg,
    rgba(255,255,255,0.15) 0%,
    rgba(255,255,255,0.15) 25%,
    rgba(255,255,255,0) 25%,
    rgba(255,255,255,0) 50%,
    rgba(255,255,255,0.15) 50%,
    rgba(255,255,255,0.15) 75%,
    rgba(255,255,255,0) 75%,
    rgba(255,255,255,0) 100%);
}

Step Six: Animated Progress Bars

If you’ve followed these steps through, then you should have already recognised the potential of CSS3 to render complex graphical effects without recourse to images and JavaScript. CSS3 can also be used simply and effectively to create impressive animated styles. The following code shows how you can display an animated progress bar that will rival the most costly JS animations.

You can modify the keyframes and animation values as you see fit, and then apply the animate class to any <span> to apply the animated progress bar effect. Have fun and enjoy!


.animate {
  animation: progress 2s linear infinite;
  -moz-animation: progress 2s linear infinite;
  -webkit-animation: progress 2s linear infinite;
  -ms-animation: progress 2s linear infinite;
  -o-animation: progress 2s linear infinite;
}

@-webkit-keyframes progress {
  from {
    background-position: 0 0;
  }
  to {
    background-position: -60px -60px;
  }
}

@-moz-keyframes progress {
  from {
    background-position: 0 0;
  }
  to {
    background-position: -60px -60px;
  }
}

@-ms-keyframes progress {
  from {
    background-position: 0 0;
  }
  to {
    background-position: -60px -60px;
  }
}

@-o-keyframes progress {
  from {
    background-position: 0 0;
  }
  to {
    background-position: -60px -60px;
  }
}

@keyframes progress {
  from {
    background-position: 0 0;
  }
  to {
    background-position: -60px -60px;
  }
}

After following these steps you will have a dynamic, professional looking progress bar that can be adapted to a number of situations and website themes. It is just one example of the many design features that can be implemented after some experimentation with CSS3 features. Most of the specific attributes of the bar, such as the color scheme, the size of the element and even the angle of the gradient shading, can be easily adapted to meld in with your design requirements.

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Kris

    Hello sara,

    What you thing about Meter like feature we got in Twitter bootstrap (look pretty same as yours).I am not sure but that thing most of the modern browser.

    Look http://twitter.github.com/bootstrap/components.html#progress

  • http://timwahrendorff.de Tim

    “Create” is a bit misleading, I think it is just styling a progress bar. At least there is no real “progress” functionality explained here, nor which css values have to be changed dynamically in order to get a living progress bar.

    • http://markadrake.com Mark Drake

      In which, a progress bar would require JavaScript.

      I’m glad you posted this Tim. I wanted to but I was lazy.

      In most cases a user’s first reaction is to look at a progress bar and expect to see progress. It’s vary rarely used to indicate progress through a survey or form – 99% of the time we are waiting for something to take place.

      So the idea of building a CSS only *progress bar* is not only confusing, but bad practice! It’s misleading, though I like the article’s use of CSS to design the bar your approach to the article makes one think this applicable to a web site. In most cases, it’s not, and you need to apply JS or some other technology to provide a good user experience.

  • momos

    Shouldn’t the actual value be part of the site instead op being part of the styling btw?

  • http://N/A RichKidFresh

    Hi. I am a noob. I wanted to know if you can elaborate on where a progress bar would come in handy and how to properly implement it?