Animated progress circle

Written by Minna Ylitalo on 10th June 2021

(Last updated 5th July 2023)

See the Pen Animated progress circle by Liquid Light (@liquidlight) on CodePen.

<script async src=""></script>

1. Create your svg with vector design software or find a suitable one online

In the final animation the gray circle is directly underneath to indicate the shape and the top gradient circle is animated. Include both circles in the same <svg> with identical coordinates to layer them.

  • Layer one circle #bar-bg for background, and another #bar for the animated progress bar on top of it
  • stroke-dasharray is the length of the circumference of the circle
  • stroke-dashoffset is used to control the location of a point on the path and this value will be animated later with JS
<svg class="svg" height="220" viewPort="0 0 110 110" version="1.1" xmlns="[<>](<>)">
    <circle id="bar-bg" r="98" cx="110" cy="110" fill="transparent" stroke-dasharray="615.752" stroke-dashoffset="615.752"></circle>
    <circle id="bar" r="98" cx="110" cy="110" fill="transparent" stroke-dasharray="615.752" stroke-dashoffset="615.752"></circle>

2. Set stroke-dashoffset in CSS

  • Set some styles and css animation transition on the circle elements and set background stroke-dashoffset to 0 to cover the whole circle
  • Add a gradient colour to the stroke of your top bar by defining the colours inside the svg and calling it in the CSS
  • I want the animation to start from the top of the circle so I've rotated the whole svg by 90 degrees.
    <linearGradient id="linear" x1="0" x2="1" y1="0" y2="0">
		<stop offset="0%"   stop-color="#DD2C41"/>
		<stop offset="100%" stop-color="#202050"/>
.svg {
    transform: rotate(-90deg);
    margin: auto;
    circle {
	    transition: stroke-dashoffset 1s linear;
	    stroke-width: 1.5em;
	    stroke: var(--neutralLight);
    #bar-bg {
	    stroke-dashoffset: 0;
    #bar {
	    stroke: url('#linear');

3. Create the functionality

  • For this example I've added an input field in the markup to set a value for the progress and limited the value between 0 and 100.
  • For added usability we also want to display the value as a number in the middle of the circle
  • You will need to convert the input % figure to a pixel value for the circle with the equations shown below and set the CSS property for stroke-dashoffset with your Javascript. You have already set your transition on the circle in the CSS file, which defines the animation when the value changes.
var circle = $('.svg #bar'),
r = circle.attr('r'),
c = Math.PI * r * 2,
pct = ((100 - value) / 100) * c; // Calculate the precentage of the svg dasharray length

// Set progress stroke length in css
circle.css({strokeDashoffset: pct});

4. Last thing to do is to display the percentage value in the middle of the circle (replace default 0% set in the html file)

$('.percentage').html(value + '%');

To understand more how line animations with svg's are constructed have a look at this article.

This article was posted in Development by Minna Ylitalo

  • Minna Ylitalo

    Minna Ylitalo

    Our junior front-end developer, Minna is passionate about all things code. By day, she smashes through CSS and JS on projects like it’s nothing, and by night, she organises codebar Brighton. When she needs time away from the keyboard, Minna hits the local countryside for a walk in the fresh air.