CodePen

HTML

            
              <div id="spinner"></div>
            
          
!

CSS

            
              /*
If you change the $ballCount count, don't forget to increase the createBalls in the styles as well.
*/
$radius = 500px
$ballSize = 60px
$ballCount = 8
$duration = 1s
$spokeColor = rgba(255,255,255,0.0)

$delayAmt = ($duration/$ballCount)
$pathAngle = 180/$ballCount

@keyframes ballMove 
  0% { transform: translate(0,0) } 
  100% { transform: translate($radius - $ballSize,0) }

body 
  background : #333
  text-align : center

#spinner
  background : transparent
  width : $radius 
  height : $radius 
  border-radius : 50%
  position : relative
  margin : 0 auto
  for i in 0..$ballCount
    &::x-spinner-path{i+1}
      transform : rotate((i*$pathAngle)deg)
      width : 100%
      height : 1px
      position : absolute
      top : 50%
      left : 0%
      background-color: $spokeColor
    &::x-spinner-ball{i+1}
      display : block
      position : absolute
      top : -($ballSize/2)px
      width : $ballSize
      height : @width
      box-shadow : 0 0 10px rgba(0,0,0,0.75)
      border : 1px solid rgba(0,0,0,0.5)
      border-radius : 50%
      animation-name : ballMove
      animation-duration : $duration
      animation-timing-function : ease-in-out
      animation-iteration-count : infinite
      animation-direction : alternate      
      animation-delay : (i*$delayAmt)
      background-color : hsla((360/$ballCount)*i, 100%, 50%, 1)

            
          
!
? ?
? ?
Must be a valid URL.
+ add another resource
via CSS Lint

JS

            
              $(function(){
createSpinner('#spinner', 8);

// Create a Shadow DOM element
function createSpinner (id, dotCount) {
  var host = document.querySelector(id);
  var shadow = host.createShadowRoot();
  shadow.innerHTML = createDots(dotCount);
}

// Generate the Template
function createDots(num) {
  var result = '';
  for (i=1; i<num+1; i++) { 
    result += '<div class="path p'+i+'" pseudo="x-spinner-path'+i+'"><div pseudo="x-spinner-ball'+i+'"></div></div>'; 
  }
  return result;
}
});
            
          
!
Must be a valid URL.
+ add another resource
via JS Hint
Loading ..................