I set out to create a circular progress bar using CSS for a site I am working on. This is what I learned in the process.
- I wanted to play with CSS gradients so.. it had to be colorful!
- Colors should not be repeated in the bar.
- The site I am working on requires 4 or so different states, so it's more like a "stepper" than a progress bar.
- The progress bar should be animatable.
- React circular progress bar NPM package Functionality-wise pretty much what I wanted (except for the gradients) to do plus more but built with SVG and React. Maybe I could customize it but I felt more like doing something new.
- Pure CSS radial progress bar Codepen: this one uses the same trick with rotating rectangulars mentioned in Lea Verou's article but for the border. Unfortunately it also uses the
clipproperty which is deprecated.. Also, no gradient.
This is what "I" came up with with quite some help from the internets.
- Using 2 background linear gradients.
- I started by using the
border-radiusfor rounded corners. However as these [don't work together] (https://stackoverflow.com/questions/5706963/possible-to-use-border-radius-together-with-a-border-image-which-has-a-gradient) I used the workaround in the answers below of 2 circles with different radius, one covering the other. This technique is used in all 3 solutions either as an pseudoelement or a regular one.
- Because I needed different colors on the bar, I used the method of 2 half circles as shown here from Steve Marx.
- I started by using the
Limitations: the calculations get complicated for intermediate steps. Notice that the colors don't always stay in the same position for different percentages because of how gradient works. For example 75% vs 87.5%. Also because it's done with linear gradient the bar is cut of in a weird angle.. you can set another angle in the gradient but for some values it will always look weird. You can stack linear gradients too.
Using stacked radial gradients (it's weird to get the colors you need)
After implementing my solution I came across Lea’s conic gradient polyfill (again mentioned by Sarah Soueidan on her excellent CSS vs SVG roundup). Here you need a normal element because we are using a polyfill.
What I learned
- SVG is a better tool for that :)
percentagefunction, interpolation and "-" sign need a space before and after
- Codepen: you can print out Sass output in console and you can save a pen in a Gist <3
- CSS: Css transitions don't work with gradients (I used opacity instead)
- Polyfill's and pseudoelements don't work together.