Let's create a Harvey Ball Progress Indicator using CSS
A few weeks ago, I worked on a feature for a web application. One small part of that feature was to display a progress indicator for a task. I decided to use something called Harvey Balls for this.
These are my own requirements for the solutions:
- It should be simple.
- It should be written purely in CSS.
- It should be defined by CSS classes that can be applied to a single
div
orspan
element, turning it into a progress indicator.
Let’s start
As I was thinking about a solution, I came across something called conic-gradient
. Let’s use it.
First, let’s define a CSS class that transforms a div
/ span
element into a circle:
|
|
Then, we create additional classes to describe the filling of the circle in quarter steps as the progress:
|
|
Now, let’s use it in HTML:
|
|
VoilĂ , the result:
Full code for this section Check it out on CodePen
Let’s improve it
But it’s possible to improve it and make it more flexible and customizable. Here’s my improved version:
|
|
- Let’s introduce and use variables like
--value
,--size
and--color
. - Since a circle has equal width and height, we can get rid of the hight by settings
aspect-ratio: 1 / 1
. - Move
background
to the.progress-indicator
class. - Override the
--value
variable in the step-classes.
That’s much better, at least in my opinion
One advantage of this solution is that it’s easy to set arbitrary values:
|
|
Full code for this section Check it out on CodePen
Let’s place the cherry on top
As a software engineer, I propose that we clamp the --value
variable to ensure that only valid values are used in the conic-gradient
.
clamp(0%, var(--value), 100%)
will ensure that the value used is between 0% and 100%, not below or above those limits.
|
|
Full code for this section Check it out on CodePen
Let’s keep it in mind for the future
CSS provides a function called attr()
that can be used to retrieve the value of an attribute of the selected element and use it in the stylesheet1.
However, support for properties other than content
is experimental1. Keep an eye on the attr() - Browser Compatibility page for updates on this improvement.
Let’s assume that today is the day when all major browsers support attr()
for all properties.
We can rewrite progress-indicator
as follows:
|
|
The value can be set by a custom HTML attribute called data-value
(see Using data attributes).
|
|
Let’s finalize this post
Feel free to contact me anytime with feedback, questions, or just to say hello. You can find my contact channels in the footer. I’m always happy to help and love hearing from people, so don’t hesitate to reach out!
You can find the original statements in the MDN Web Docs attr() documentation. ↩︎ ↩︎