Build Step Progress Bar (css and jquery)

enter image description here

You've seen iterations of this type of progress bar on sites like paypal. How does one go about setting this up using CSS and jquery? I have 4 pages and each page is a step... so 4 steps.


Solution 1:

I have searched for a solution that will visualize process steps in my web application. I have found the following excellent write-up by Stephen A Thomas:

Tracking Progress in Pure CSS (Original Link now dead)

In his approach Thomas even gets away with just using CSS - no Javascript! In an essence the following CSS code from his article does the trick for me:

    <style>

    <!-- Progress with steps -->

    ol.progtrckr {
        margin: 0;
        padding: 0;
        list-style-type: none;
    }

    ol.progtrckr li {
        display: inline-block;
        text-align: center;
        line-height: 3em;
    }

    ol.progtrckr[data-progtrckr-steps="2"] li { width: 49%; }
    ol.progtrckr[data-progtrckr-steps="3"] li { width: 33%; }
    ol.progtrckr[data-progtrckr-steps="4"] li { width: 24%; }
    ol.progtrckr[data-progtrckr-steps="5"] li { width: 19%; }
    ol.progtrckr[data-progtrckr-steps="6"] li { width: 16%; }
    ol.progtrckr[data-progtrckr-steps="7"] li { width: 14%; }
    ol.progtrckr[data-progtrckr-steps="8"] li { width: 12%; }
    ol.progtrckr[data-progtrckr-steps="9"] li { width: 11%; }

    ol.progtrckr li.progtrckr-done {
        color: black;
        border-bottom: 4px solid yellowgreen;
    }
    ol.progtrckr li.progtrckr-todo {
        color: silver; 
        border-bottom: 4px solid silver;
    }

    ol.progtrckr li:after {
        content: "\00a0\00a0";
    }
    ol.progtrckr li:before {
        position: relative;
        bottom: -2.5em;
        float: left;
        left: 50%;
        line-height: 1em;
    }
    ol.progtrckr li.progtrckr-done:before {
        content: "\2713";
        color: white;
        background-color: yellowgreen;
        height: 1.2em;
        width: 1.2em;
        line-height: 1.2em;
        border: none;
        border-radius: 1.2em;
    }
    ol.progtrckr li.progtrckr-todo:before {
        content: "\039F";
        color: silver;
        background-color: white;
        font-size: 1.5em;
        bottom: -1.6em;
    }

</style>

As well as HTML tags from his example (I use Grails GSP pages to generate tags and 'done/todo' class dynamically):

<ol class="progtrckr" data-progtrckr-steps="5">
    <li class="progtrckr-done">Order Processing</li>
    <li class="progtrckr-done">Pre-Production</li>
    <li class="progtrckr-done">In Production</li>
    <li class="progtrckr-done">Shipped</li>
    <li class="progtrckr-todo">Delivered</li>
</ol>

Hope it helps. Works pretty well for me.


UPDATE: The following (shortened) version also works well.

    ol.progtrckr {
        display: table;
        list-style-type: none;
        margin: 0;
        padding: 0;
        table-layout: fixed;
        width: 100%;
    }
    ol.progtrckr li {
        display: table-cell;
        text-align: center;
        line-height: 3em;
    }
    ... and the rest of the CSS ...

    <ol class="progtrckr">
        ...
    </ol>

display: table; table-layout: fixed; width: 100% ensure that the list items are automatically sized equally as long as the content does not overflow. There is no need to use data-progtrckr-steps and its associated CSS.

Solution 2:

There are a lot of very nice answers on this page and I googled for some more, but none of the answers ticked all the checkboxes on my wish list:

  • CSS only, no Javascript
  • Stick to Tom Kenny's Best Design Practices
  • Layout like the other answers
  • Each step has a name and a number
  • Responsive layout: font size independent
  • Fluid layout: the list and its items scale with the available width
  • The names and numbers are centered in their block
  • The "done" color goes up to and including the active item, but not past it.
  • The active item should stand out graphically

So I mixed the code of several examples, fixed the things that I needed and here is the result:

Progress Tracker v2

I used the following CSS and HTML:

/* Progress Tracker v2 */
ol.progress[data-steps="2"] li { width: 49%; }
ol.progress[data-steps="3"] li { width: 33%; }
ol.progress[data-steps="4"] li { width: 24%; }
ol.progress[data-steps="5"] li { width: 19%; }
ol.progress[data-steps="6"] li { width: 16%; }
ol.progress[data-steps="7"] li { width: 14%; }
ol.progress[data-steps="8"] li { width: 12%; }
ol.progress[data-steps="9"] li { width: 11%; }

.progress {
    width: 100%;
    list-style: none;
    list-style-image: none;
    margin: 20px 0 20px 0;
    padding: 0;
}

.progress li {
    float: left;
    text-align: center;
    position: relative;
}

.progress .name {
    display: block;
    vertical-align: bottom;
    text-align: center;
    margin-bottom: 1em;
    color: black;
    opacity: 0.3;
}

.progress .step {
    color: black;
    border: 3px solid silver;
    background-color: silver;
    border-radius: 50%;
    line-height: 1.2;
    width: 1.2em;
    height: 1.2em;
    display: inline-block;
    z-index: 0;
}

.progress .step span {
    opacity: 0.3;
}

.progress .active .name,
.progress .active .step span {
    opacity: 1;
}

.progress .step:before {
    content: "";
    display: block;
    background-color: silver;
    height: 0.4em;
    width: 50%;
    position: absolute;
    bottom: 0.6em;
    left: 0;
    z-index: -1;
}

.progress .step:after {
    content: "";
    display: block;
    background-color: silver;
    height: 0.4em;
    width: 50%;
    position: absolute;
    bottom: 0.6em;
    right: 0;
    z-index: -1;
}

.progress li:first-of-type .step:before {
    display: none;
}

.progress li:last-of-type .step:after {
    display: none;
}

.progress .done .step,
.progress .done .step:before,
.progress .done .step:after,
.progress .active .step,
.progress .active .step:before {
    background-color: yellowgreen;
}

.progress .done .step,
.progress .active .step {
    border: 3px solid yellowgreen;
}
<!-- Progress Tracker v2 -->
<ol class="progress" data-steps="4">
    <li class="done">
        <span class="name">Foo</span>
        <span class="step"><span>1</span></span>
    </li>
    <li class="done">
        <span class="name">Bar</span>
        <span class="step"><span>2</span></span>
    </li>
    <li class="active">
        <span class="name">Baz</span>
        <span class="step"><span>3</span></span>
    </li>
    <li>
        <span class="name">Quux</span>
        <span class="step"><span>4</span></span>
    </li>
</ol>

As can be seen in the example above, there are now two list item classes to take note of: active and done. Use class="active" for the current step, use class="done" for all steps before it.

Also note the data-steps="4" in the ol tag; set this to the total number of steps to apply the correct size to all list items.

Feel free to play around with the JSFiddle. Enjoy!

Solution 3:

Here is how to make one:

http://24ways.org/2008/checking-out-progress-meters

Here are some inspiration examples:

http://www.smashingmagazine.com/2010/01/15/progress-trackers-in-web-design-examples-and-best-design-practices/