Last Updated: April 23, 2019
·
30.47K
· carlosescri

Simple, CSS only wizard progress tracker

This is a small tutorial about how to create a very simple UI widget to tell users in what step of a process they are.

Picture


We will start with a small piece of HTML:

<ol class="track-progress">
  <li>
    Site Information
  </li>
  <li>
    Data Source
  </li>
  <li>
    Final Details
  </li>
</ol>

Now, we are going to reset the ordered list styles and make the list elements be displayed in a single line. We will get this CSS:

.track-progress {
  margin: 0;
  padding: 0;
  overflow: hidden;
}

.track-progress li {
  list-style-type: none;
  display: inline-block;

  position: relative;
  margin: 0;
  padding: 0;

  text-align: center;
  line-height: 30px;
  height: 30px;

  background-color: #f0f0f0;
}

You will get something like this:

Picture

Lets make this tracker occupy all the available width. For the sake of flexibility we are going to add a HTML attribute to the tracker <ol> tag to declare the number of steps in the process. This way we can add some default widths that we will use by changing the attribute value.

The HTML:

<ol class="track-progress" data-steps="3">
  <li>
    Site Information
  </li>
  <li>
    Data Source
  </li>
  <li>
    Final Details
  </li>
</ol>

The CSS:

.track-progress[data-steps="3"] li { width: 33%; }
.track-progress[data-steps="4"] li { width: 25%; }
.track-progress[data-steps="5"] li { width: 20%; }

This looks promising:

Picture

To remove the annoying blank space we will have to remove the blank space between the <li> tags. We can do it with HTML comments:

 <ol class="track-progress" data-steps="3">
   <li>
     Site Information
   </li><!--
--><li>
     Data Source
   </li><!--
--><li>
     Final Details
   </li>
 </ol>

Much better:

Picture

The idea of adding the steps attribute and the HTML comments was taken from here. That article was also the main source of inspiration for writing my own progress tracker.

I want to add some kind of arrows to indicate the actual direction in the sequence of steps so I need extra markup to isolate the step content from the rest of the decorative stuff:

 <ol class="track-progress" data-steps="3">
   <li class="done">
     <span>Site Information</span>
   </li><!--
--><li class="done">
     <span>Data Source</span>
   </li><!--
--><li>
     <span>Final Details</span>
   </li>
 </ol>

I've added a done class to represent the progress with different styles. Here is the CSS:

.track-progress li > span {
  display: block;

  color: #999;
  font-weight: bold;
  text-transform: uppercase;
}

.track-progress li.done > span {
  color: #666;
  background-color: #ccc;
}

And the result:

Picture

To add the arrows we will use the :before and :after pseudo-elements and the trick of giving borders a huge size to create corners:

.track-progress li > span:after,
.track-progress li > span:before {
  content: "";
  display: block;
  width: 0px;
  height: 0px;

  position: absolute;
  top: 0;
  left: 0;

  border: solid transparent;
  border-left-color: #f0f0f0;
  border-width: 15px;
}

.track-progress li > span:after {
  top: -5px;
  z-index: 1;
  border-left-color: white;
  border-width: 20px;
}

.track-progress li > span:before {
  z-index: 2;
}

You get the idea:

Picture

Now we apply styles correctly to make the arrow colors match the state of the previous step and remove the arrow in the first element:

.track-progress li.done + li > span:before {
  border-left-color: #ccc;
}

.track-progress li:first-child > span:after,
.track-progress li:first-child > span:before {
  display: none;
}

Picture

Now we want to add the arrow appearance at the beginning and the end of the tracker so we have to add more markup:

 <ol class="track-progress" data-steps="3">
   <li class="done">
     <span>Site Information</span>
     <i></i>
   </li><!--
--><li class="done">
     <span>Data Source</span>
   </li><!--
--><li>
     <span>Final Details</span>
     <i></i>
   </li>
 </ol>
.track-progress li:first-child i,
.track-progress li:last-child i {
  display: block;
  height: 0;
  width: 0;

  position: absolute;
  top: 0;
  left: 0;

  border: solid transparent;
  border-left-color: white;
  border-width: 15px;
}

.track-progress li:last-child i {
  left: auto;
  right: -15px;

  border-left-color: transparent;
  border-top-color: white;
  border-bottom-color: white;
}

Picture

6 Responses
Add your response

Excellent, thanks!

over 1 year ago ·

Thank you,

over 1 year ago ·

This is the most helpful article for css on progress tracker I've ever found. Brava.

over 1 year ago ·

Thanks..

over 1 year ago ·

This is great! But do you know how I can make it mobile responsive?

over 1 year ago ·

Hi,
Can I know how to be able to click on the "Data Source" bar when I at the "Final Details" page so that I can get back to the previous page?

Thanks.

over 1 year ago ·