<ul class="js">
  <li></li>
  <li></li>
</ul>
<ul class="css">
  <li></li>
  <li></li>
</ul>

<a href="https://danielcwilson.com/blog/2015/07/animations-part-1" target="_blank">Learn about the Web Animations API</a>
$primary: #dedfee;
$secondary: #d05f5e;
$background: #135569;

body {
  background: $background;
}
ul {
  display: inline-block;
  width: 6rem;
}
li {
  background: $primary;
  height: 4rem;
  width: 4rem;
  display: block;
  margin: 2rem 0 2rem 2rem;
  border-radius: 1rem;
  
  .css.activated & {
    background: $secondary;
    animation: translation 3s 0s infinite linear;
  }
  &:last-child {
    //margin-bottom: 5px;
  }
}

@keyframes translation {
  0% { transform: rotate(0deg) }
  8% { transform: rotate(-12deg) }
  30% { transform: rotate(270deg) }
  55% { transform: rotate(-40deg) }
  80% { transform: rotate(70deg) }
  92% { transform: rotate(-13deg) }
  100% { transform: rotate(0deg) }
}




a {
  position: absolute;
  bottom: 0;
  padding: 1rem;
  left: 0;
  right: 0;
  color: #fafbff;
  background: #fafbff20;
  font-family: system-ui, sans-serif;
}
View Compiled
var elements = document.querySelectorAll('.js li');
var animations = [];

for (var i = 0, len = elements.length; i < len; ++i) {
  var animation = elements[i].animate([
    { transform: 'rotate(0deg)', offset: 0 },
    { transform: 'rotate(-12deg)', offset: .08 },
    { transform: 'rotate(270deg)', offset: .3 },
    { transform: 'rotate(-40deg)', offset: .55 },
    { transform: 'rotate(70deg)', offset: .8 },
    { transform: 'rotate(-13deg)', offset: .92 },
    { transform: 'rotate(0deg)', offset: 1 }
  ], {
    duration: 3000,
    iterations: Infinity,
    easing: 'linear',
    delay: 0
  });
  
  animations.push(animation);
}
document.querySelector('.css').classList.add('activated');

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://danielcwilson.com/js/web-animations-next-lite.min.js