Create and Filling arc progressively with css - circle progress bar

12,691

Solution 1

You can use an SVG with two arc on on top of the other and then use stroke-dash-array.

svg {
  height: 90vh;
  margin: auto;
  display: block;
}

path {
  stroke-linecap: round;
  stroke-width: 2;
}

path.grey {
  stroke: lightgrey;
}

path.purple {
  stroke: purple;
  stroke-dasharray: calc(40 * 3.142 * 1.85);
  stroke-dashoffset: 20;
  /* adjust last number for variance */
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 100 100">
    <path class="grey" d="M40,90
             A40,40 0 1,1 60,90"
          style="fill:none;"/>
    <path class="purple" d="M40,90
             A40,40 0 1,1 60,90"
          style="fill:none;"/>
</svg>

Solution 2

Using SVG is the best way to create an arc like this. Here is the solution with all iterations of the loader:

.progress-wrapper {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: space-around;
}

path {
  stroke-linecap: round;
  stroke-width: 6;
}

.grey {
  stroke: #e5e5e5;
}

.red {
  stroke: #e33800;
  stroke-dasharray: 248;
  stroke-dashoffset: 240;
  /* adjust last number for variance */
}

.red-02 {
  stroke-dashoffset: 220;
}

.red-03 {
  stroke-dashoffset: 200;
}

.red-04 {
  stroke-dashoffset: 180;
}

.red-05 {
  stroke-dashoffset: 160;
}

.red-06 {
  stroke-dashoffset: 140;
}

.red-07 {
  stroke-dashoffset: 120;
}

.red-08 {
  stroke-dashoffset: 100;
}

.red-09 {
  stroke-dashoffset: 50;
}

.red-10 {
  stroke-dashoffset: 0;
}
<div class="progress-wrapper">
  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
      <path class="grey" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
      <path class="red" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
  </svg>
  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
      <path class="grey" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
      <path class="red red-02" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
  </svg>
  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
      <path class="grey" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
      <path class="red red-03" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
  </svg>
  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
      <path class="grey" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
      <path class="red red-04" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
  </svg>
  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
      <path class="grey" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
      <path class="red red-05" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
  </svg>
  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
      <path class="grey" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
      <path class="red red-06" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
  </svg>
  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
      <path class="grey" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
      <path class="red red-07" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
  </svg>
  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
      <path class="grey" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
      <path class="red red-08" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
  </svg>
  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
      <path class="grey" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
      <path class="red red-09" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
  </svg>
  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="37 -5 120 100" width="120" height="100">
      <path class="grey" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
      <path class="red red-10" d="M55,90
               A55,55 0 1,1 140,90"
            style="fill:none;"/>
  </svg>
</div>

https://codepen.io/shalinigandhi/pen/mdmmwdV

Share:
12,691
Elmer Dantas
Author by

Elmer Dantas

Brazilian Bachelor in Systems Information Developing for web since 2007 » .NET C# » NodeJS » Angular » React

Updated on June 06, 2022

Comments

  • Elmer Dantas
    Elmer Dantas almost 2 years

    I'm struggling to fill an arc like a progress bar because I'm not that good working with css.

    I want to achieve a "progress" arc like this: enter image description here

    I came across with this: https://codepen.io/enslavedeagle/pen/AXzaKE

    #arc,
    #arc::before {
      display: block;
      box-sizing: border-box;
      border-radius: 100%;
      width: 100px;
      height: 100px;
      position: absolute;
      background-color: transparent;
      padding: 0;
      margin: 0;
    }
    
    #arc {
      border: solid #00BBEE 12px;
      clip: rect(0px, 100px, 50px, 0px);
      margin: 25px;
    }
    
    #arc::before {
      content: '';
      border: solid black 12px;
      top: -12px;
      left: -12px;
      clip: rect(0px, 100px, 50px, 0px);
      transform: rotate(-150deg);
      /* define the fill length, using the rotation above.
         from -180deg (0% fill) to 0deg (100% fill) */
      /* if you have a better solution to make thing like this 
         work, please let me know! :) */
    }
    

    and try to customize to be like what I want to but with no sucess until now: here: https://codepen.io/anon/pen/qpNrEP

    Could any one give some help with this? Can also be alternative solution to achieve this.

    I appreciate

    Kind regards,

    • Alvarez
      Alvarez over 6 years
      can you use jquery or just css?
    • Elmer Dantas
      Elmer Dantas over 6 years
      I can use angular 4
  • Elmer Dantas
    Elmer Dantas over 6 years
    That's what I was looking for...now I just need to map the value of stroke-dashoffset to 0-100% to make the progress works. I would like to upvote one thousand times! Thank you so much! Do you mind to explain how the calc of stroke-dasharray (calc(40 * 3.142 * 1.85)) works?
  • Paulie_D
    Paulie_D over 6 years
    It's a little more complicated that it sounds as you probably need JS to determine the actual dash array and dash offset. The calc is roughly (radius * Pi * any range). It does break though if you're rough with it. As i said these are usually managed by JS. This is just to demo the concept.
  • Elmer Dantas
    Elmer Dantas over 6 years
    I'll use angular to manage, no problem. I just want to know how to draw the arc and fill it (stroke-dasharray). I asked because I'm not used to work with geometric forms...so I don't get how do you came to this result, like: why 1.85? on the calc form? If its possible could we talk on chat? Thanks again
  • Elmer Dantas
    Elmer Dantas over 6 years
    thanks but from the answer I've created a component that can be use dynamically. You can check on: elmeerr.github.io/ng2-arc-progress-demo
  • Ricardo Del Rio
    Ricardo Del Rio over 6 years
    Cool!! It's amazing. I was going to do the component but you already done that. Thanks!
  • Ricardo Del Rio
    Ricardo Del Rio over 6 years
    @ElmerDantas Have you ever tried to animate the arc from 0 to the corresponding value when the page has finished loading? Now I have that issue
  • Elmer Dantas
    Elmer Dantas over 6 years
    I don't know if I get it but, it's not the case to use a for from 0 to corresponding value and then increment the variable you use as model to fill the arc progress?
  • Milan Panic
    Milan Panic almost 5 years
    Hi, can you tell me how to make the progress bar bigger ?
  • Christophe
    Christophe over 3 years
    The screenshot looks great but the Codepen doesn't seem to work.
  • mark-vandenberg
    mark-vandenberg almost 3 years
    @Christophe Sorry for the slow reply, I just checked it and for some reason the site had to think for a good few seconds before working but it did still work without me making any changes. Did you press the button to make the progress bar appear?
  • Falko
    Falko almost 2 years
    Although I also wonder about the 1.85 (while 40 * 3.142 being the radius times pi), I found calc(40 * 3.142 * 1.85 * (1 - <fraction>)) to fill a fraction defined by a handy <fraction> given in the range from 0 to 1.
  • Falko
    Falko almost 2 years
    Ah, the 1.85 is needed to get the length of the whole arc. The full circle would be radius * pi * 2. But since the bottom piece is missing, the factor is only 1.85. The details depend on how M40,90 A40,40 0 1,1 60,90 results in a circular arc.