.spring
    -(1..30).each do |i|
        .l
            -(1..10).each do |j|
                .dot
View Compiled
$m: 30;
$n: 10;
$d: .25em;
$s: 1em;
$f: 3em;
$dev: 2em;
html { height: 100%; perspective: 32em; background: black; }
.spring, .spring *, .spring *:before, .spring *:after {
  position: absolute;
  top: 50%; left: 50%;
  border-radius: 50%;
  transform-style: preserve-3d;
}
.spring {
  animation: rot 32s linear infinite;
}
.l {
  @for $i from 0 to $m {
    &:nth-child(#{$i + 1}) {
      transform: translateY(($m/2 - $i)*$s) 
                 rotateY($i*720deg/$m) translateZ($dev) 
                 rotateY(-$i*720deg/$m);
      background: hsl($i*360/$m, 100%, 65%);
    }
  }
}
.dot {
  margin: -$d/2;
  width: $d; height: $d;
  background: inherit;
  @for $i from 0 to $n {
    &:nth-child(#{$i + 1}) {
      transform: translateY($i*$s/$n) 
                 rotateY($i*360deg/$n) translateZ($f)
    }
  }
  &:before, &:after {
    margin: inherit;
    width: inherit; height: inherit;
    background: inherit;
    content: '';
  }
  &:before { transform: rotateY(90deg); }
  &:after { transform: rotateX(90deg); }
}
@keyframes rot {
  to {
    transform: rotate(360deg) rotateY(720deg) rotateX(-360deg);
  }
}
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.