CSS Radial Loader

 View on Github  •   Download .ZIP

0%1%2%3%4%5%6%7%8%9%10%11%12%13%14%15%16%17%18%19%20%21%22%23%24%25%26%27%28%29%30%31%32%33%34%35%36%37%38%39%40%41%42%43%44%45%46%47%48%49%50%51%52%53%54%55%56%57%58%59%60%61%62%63%64%65%66%67%68%69%70%71%72%73%74%75%76%77%78%79%80%81%82%83%84%85%86%87%88%89%90%91%92%93%94%95%96%97%98%99%100%

HTML 

<div class="loader__progress" data-progress="0">
  <div class="circle">
    <div class="mask full">
      <div class="fill"></div>
    </div>
    <div class="mask half">
      <div class="fill"></div>
      <div class="fill fix"></div>
    </div>
    <div class="inset">
      <div class="percentage">
        <div class="numbers"><span>&bull;</span><span>0%</span><span>1%</span><span>2%</span><span>3%</span><span>4%</span><span>5%</span><span>6%</span><span>7%</span><span>8%</span><span>9%</span><span>10%</span><span>11%</span><span>12%</span><span>13%</span><span>14%</span><span>15%</span><span>16%</span><span>17%</span><span>18%</span><span>19%</span><span>20%</span><span>21%</span><span>22%</span><span>23%</span><span>24%</span><span>25%</span><span>26%</span><span>27%</span><span>28%</span><span>29%</span><span>30%</span><span>31%</span><span>32%</span><span>33%</span><span>34%</span><span>35%</span><span>36%</span><span>37%</span><span>38%</span><span>39%</span><span>40%</span><span>41%</span><span>42%</span><span>43%</span><span>44%</span><span>45%</span><span>46%</span><span>47%</span><span>48%</span><span>49%</span><span>50%</span><span>51%</span><span>52%</span><span>53%</span><span>54%</span><span>55%</span><span>56%</span><span>57%</span><span>58%</span><span>59%</span><span>60%</span><span>61%</span><span>62%</span><span>63%</span><span>64%</span><span>65%</span><span>66%</span><span>67%</span><span>68%</span><span>69%</span><span>70%</span><span>71%</span><span>72%</span><span>73%</span><span>74%</span><span>75%</span><span>76%</span><span>77%</span><span>78%</span><span>79%</span><span>80%</span><span>81%</span><span>82%</span><span>83%</span><span>84%</span><span>85%</span><span>86%</span><span>87%</span><span>88%</span><span>89%</span><span>90%</span><span>91%</span><span>92%</span><span>93%</span><span>94%</span><span>95%</span><span>96%</span><span>97%</span><span>98%</span><span>99%</span><span>100%</span></div>
      </div>
    </div>
  </div>
</div>

LESS 

@circle-bg:   #222;
@circle-color:  #FFF;
@circle-size: 24rem;
@inset-size:  @circle-size - 0.4;

@percentage-color: @circle-color;
@percentage-font-size: 16px;
@percentage-text-width: 60px;

@transition-length: 1s;

.experiment__loader{
  width: @circle-size;
  height: @circle-size;
  margin: 4rem auto;
}

.loader__progress{
  position: relative;
  background-color: @circle-bg;
  width: @circle-size;
  height: @circle-size;

  -webkit-border-radius: 50%;
  -moz-border-radius: 50%;
  border-radius: 50%;
  
  .circle {
    .mask, .fill {
      position: absolute;
      width: @circle-size;
      height: @circle-size;

      -webkit-border-radius: 50%;
      -moz-border-radius: 50%;
      border-radius: 50%;
      
      -webkit-transition: -webkit-transform @transition-length;
      -moz-transition: -moz-transform @transition-length;
      -o-transition: -o-transform @transition-length;
      transition: transform @transition-length;

      -webkit-backface-visibility: hidden;
      -moz-backface-visibility: hidden;
      -ms-backface-visibility: hidden;
      -o-backface-visibility: hidden;
      backface-visibility: hidden;
    }
    .mask{
      clip: rect(0rem, @circle-size, @circle-size, @circle-size/2);
      .fill {
        clip: rect(0rem, @circle-size/2, @circle-size, 0rem);
        background-color: @circle-color;
      }
    }
    .inset{
      position: absolute;
      width: @inset-size;
      height: @inset-size;
      margin-left: -@inset-size/2;
      margin-top: -@inset-size/2;
      top: 50%;
      left: 50%;
      background: @base-color;

      -webkit-border-radius: 50%;
      -moz-border-radius: 50%;
      border-radius: 50%;

      .percentage {
        height: @percentage-font-size;
        width: @percentage-text-width;
        overflow: hidden;
        
        position: absolute;
        top: 50%;
        left: 50%;

        margin-top: -@percentage-font-size/2;
        margin-left: -@percentage-text-width/2;
        line-height: 1;

        .numbers {
          text-align: left;
          margin-top: -@percentage-font-size;
          transition: width @transition-length;

          span {
            width: @percentage-text-width;
            display: inline-block;
            vertical-align: top;
            text-align: center;
            font-size: @percentage-font-size;
            color: @percentage-color;
          }
        }
      }
    }
  }

  @i: 0;
  @increment: 180deg / 100;
  
  .loop (@i) when (@i <= 100) {
    &[data-progress="@{i}"] {
      .circle {
        .mask.full, .fill {
          -webkit-transform: rotate(@increment * @i);
          -ms-transform: rotate(@increment * @i);
          transform: rotate(@increment * @i);
        } 
        .fill.fix {
          -webkit-transform: rotate(@increment * @i * 2);
          -ms-transform: rotate(@increment * @i * 2);
          transform: rotate(@increment * @i * 2);
        }
        .inset .percentage .numbers {
          width: @i * @percentage-text-width + @percentage-text-width;
        }
      }
    }
    .loop(@i + 1);
  }
  .loop(@i);
}

JavaScript 

$(document).ready(function(){
  
  var changePercentage = function() {
    this.percentage = 0;
  };

  window.onload = function() {
        
      var progress = new changePercentage();

      var gui = new dat.GUI();
          gui.add(progress, 'percentage', 0, 100);

      var updateProgress = function() {
        var rotation = Math.floor(progress.percentage);
        $('.loader__progress').attr('data-progress', rotation);
      };
      setInterval( updateProgress, 500 );

  };
});