<- all articles

DIY Progress Bars 📊

As a front-end developer, you’re often confronted with a task that seems too difficult or would take up too much of your time to begin with, or you’re not really willing to go the extra length to create something yourself, and so, you reach out to look for a library that does it for you.

While many developers are lazy, would praise this, and say: “it’s great when you can re-use existing libraries” (I would too usually), in some cases, you can create things yourself. This often takes not more than a few hours, and you can learn something from it while having full control. I found that for most of these things I end up saving time not fighting a library when I do them myself. Of course, it’s also just plainly cool when you get to make things yourself.

In this blog, I want to quickly go over creating multi-segment progress bars with Vue, make them look nice and minimal, and then go over some of the options and future improvements.

Making progress 🛠

Here’s the CodePen if you want to follow along.

Progress bars seem daunting because they can double as charts, and when developers like you and I think of charts, it feels quite intimidating to write that yourself. Actually, in the case of progress bars, these items are very simple and straightforward. Let’s begin by just simply outlining our progress bar:

Outline markup for progress bars

This describes a parent element for the entire bar, and the segment inside of it is what we will use to display the amount of progress.

Styling for our bar
Basic Progress Bar

Great! So we gave the progress bar parent a bit of body. Some height and background-color so it’s at least visible. The border-radius is equal to the height, so the edges are perfectly rounded. We set overflow to hidden so the segment will be hidden outside the parent container. The display: flex is not mandatory, but in a bit, I’ll show you why I’ve added this.

I’m working in Vue so let’s define the data that we want to show first:

The data

I mentioned before that progress bars can double as charts. Let’s make a mini-BI tool to display some data with our bar. I’ve added a customer satisfaction entry in our data with some properties. I’ve added an amount and then an entry bar containing a segment.

Bend segments to your will

We then iterate over segments using v-for and style the bars explicitly with the data per segment. We define the background color and width in percentage.

Displaying percentage

You might have wondered why I defined an Array and display: flex before. These bars are much more powerful when displaying more data in different colors (of course, making sure there’s a legend or consensus about their meaning). So we can add new segment objects to the bar array we defined before, and they will be displayed appropriately:

Multiple segments

If we clean things up a bit, add some items that can display the overall value, and give each bar a title, we end up with something that can be useful as a BI tool:

The result


It’s relatively easy to create the more sophisticated stuff yourself than trying to fight a library. Sometimes, it’s smooth sailing with a library, but when it’s not, you’re losing more time than making your own stuff. This demo was made in under an hour, and it was fun too.

Of course, we’re just touching on the subject. We didn’t consider what happens when all segments exceed 100%, and we assume all our data is in a percentage. Usually, we have actual numbers. In those cases, you can run down the max value of a group and convert all values in that group into a percentage of the max to make segments out of that. The choice is yours.

Progress element

There’s something I forgot to mention. If you want to make progress bars which semantically are not graphs nor figures, and only have 1 segment/value, you are best to use the correct html tag for that. The <progress /> tag if preferred in such cases. The styling is slightly different, but similar. Here’s the MDN page where you can read more about it. For multi-segment bars or graphs, this blog is still relevant.

Written by

Want to know more?

Related articles