<div class="surface">
  <div class="element bull0"></div>
  <div class="element bull1"></div>
  <div class="element bull2"></div>
  <div class="element bull3"></div>
  <div class="element bull4"></div>
  <div class="element bull5"></div>
  <div class="element bull6"></div>
  <div class="element bull7"></div>
</div>
:root {
  --surface-color: #CDE5E2;
  --surface-color-shadow: #9CB4B7;
  --element-color: #E69ECB;
  
  --surface-diameter: 30vw;
  --element-diameter: 3vw;

  --sqrt2: 1.414213562373095;
  --sqrt3: 1.732050807568877;

  --r: -15vw;
  --sin67-5: 0.92388;
  --cos67-5: 0.38268;

  /*
  Circles and their starting/ending positions will be numbered starting at 0
  and will be positioned clockwise starting at the top. So that 0 is where 12
  is on a clock and 8 where 6 is. */
  --pos-0-x:      0;
  --pos-0-y:      var(--r);
  --pos-8-x:      0;
  --pos-8-y:      calc(var(--r) * -1);

  --pos-4-x:      calc(var(--r) * -1);
  --pos-4-y:      0;
  --pos-12-x:     var(--r);
  --pos-12-y:     0;

  --pos-2-x:     calc((var(--r) * -1) / var(--sqrt2));
  --pos-2-y:     calc( var(--r)       / var(--sqrt2));
  --pos-10-x:    calc( var(--r)       / var(--sqrt2));
  --pos-10-y:    calc((var(--r) * -1) / var(--sqrt2));

  --pos-6-x:     calc((var(--r) * -1) / var(--sqrt2));
  --pos-6-y:     calc((var(--r) * -1) / var(--sqrt2));
  --pos-14-x:    calc( var(--r)       / var(--sqrt2));
  --pos-14-y:    calc( var(--r)       / var(--sqrt2));

  --pos-1-x:     calc(var(--cos67-5) * (var(--r) * -1));
  --pos-1-y:     calc(var(--sin67-5) *  var(--r));
  --pos-9-x:     calc(var(--cos67-5) *  var(--r));
  --pos-9-y:     calc(var(--sin67-5) * (var(--r) * -1));

  --pos-3-x:     calc(var(--sin67-5) * (var(--r) * -1));
  --pos-3-y:     calc(var(--cos67-5) *  var(--r));
  --pos-11-x:    calc(var(--sin67-5) *  var(--r));
  --pos-11-y:    calc(var(--cos67-5) * (var(--r) * -1));

  --pos-5-x:     calc(var(--sin67-5) * (var(--r) * -1));
  --pos-5-y:     calc(var(--cos67-5) * (var(--r) * -1));
  --pos-13-x:    calc(var(--sin67-5) *  var(--r));
  --pos-13-y:    calc(var(--cos67-5) *  var(--r));

  --pos-7-x:     calc(var(--cos67-5) * (var(--r) * -1));
  --pos-7-y:     calc(var(--sin67-5) * (var(--r) * -1));
  --pos-15-x:    calc(var(--cos67-5) *  var(--r));
  --pos-15-y:    calc(var(--sin67-5) *  var(--r));

}
html, body {
  width: 100%; height: 100%;
}
body {
  position: relative;
  background:
    linear-gradient(135deg, var(--surface-color), var(--surface-color-shadow));
}

.surface,
.element { border-radius: 100%; }

.surface { 
  background: rgba(0,0,0,.03);
  box-shadow:
    inset 2px 2px 2px rgb(0 0 0 / 5%),
    2px 2px 2px rgb(255 255 255 / 25%);

  overflow: hidden;
  width:  var(--surface-diameter);
  height: var(--surface-diameter);
  padding: calc(var(--element-diameter)/2);

  margin: auto; position: absolute;
  top: 0; left: 0; right: 0; bottom: 0; }

.element {
  background: var(--element-color);
  box-shadow:
    1px 1px 3px rgb(0 0 0 / 10%),
    inset -1px -1px 1px rgb(0 0 0 / 10%),
    inset 1px 1px 1px rgb(255 255 255 / 52%);

  position: absolute;
  width:  var(--element-diameter);
  height: var(--element-diameter);

  margin: auto; position: absolute;
  top: 0; left: 0; right: 0; bottom: 0; 

    animation-duration: 4s;
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
    animation-direction: alternate;
}

.bull0 { 
    transform:
      translateX(var(--pos-0-x))
      translateY(var(--pos-0-y)); 
    animation-name: bull0; 
    animation-delay: 0s; }
.bull1 { 
    transform:
      translateX(var(--pos-1-x))
      translateY(var(--pos-1-y)); 
    animation-name: bull1; 
    animation-delay: .5s; }
.bull2 { 
    transform:
      translateX(var(--pos-2-x))
      translateY(var(--pos-2-y)); 
    animation-name: bull2; 
    animation-delay: 1s; }
.bull3 { 
    transform:
      translateX(var(--pos-3-x))
      translateY(var(--pos-3-y)); 
    animation-name: bull3; 
    animation-delay: 1.5s; }
.bull4 { 
    transform:
      translateX(var(--pos-4-x))
      translateY(var(--pos-4-y)); 
    animation-name: bull4; 
    animation-delay: 2s; }
.bull5 { 
    transform:
      translateX(var(--pos-5-x))
      translateY(var(--pos-5-y)); 
    animation-name: bull5; 
    animation-delay: 2.5s; }
.bull6 { 
    transform:
      translateX(var(--pos-6-x))
      translateY(var(--pos-6-y)); 
    animation-name: bull6; 
    animation-delay: 3s; }
.bull7 { 
    transform:
      translateX(var(--pos-7-x))
      translateY(var(--pos-7-y)); 
    animation-name: bull7; 
    animation-delay: 3.5s; }


@keyframes bull0 {
  0%   {
    transform:
      translateX(var(--pos-0-x))
      translateY(var(--pos-0-y)); }
  100% {
    transform:
      translateX(var(--pos-8-x))
      translateY(var(--pos-8-y)); }
}
@keyframes bull1 {
  0%   {
    transform:
      translateX(var(--pos-1-x))
      translateY(var(--pos-1-y)); }
  100% {
    transform:
      translateX(var(--pos-9-x))
      translateY(var(--pos-9-y)); }
}
@keyframes bull2 {
  0%   {
    transform:
      translateX(var(--pos-2-x))
      translateY(var(--pos-2-y)); }
  100% {
    transform:
      translateX(var(--pos-10-x))
      translateY(var(--pos-10-y)); }
}
@keyframes bull3 {
  0%   {
    transform:
      translateX(var(--pos-3-x))
      translateY(var(--pos-3-y)); }
  100% {
    transform:
      translateX(var(--pos-11-x))
      translateY(var(--pos-11-y)); }
}
@keyframes bull4 {
  0%   {
    transform:
      translateX(var(--pos-4-x))
      translateY(var(--pos-4-y)); }
  100% {
    transform:
      translateX(var(--pos-12-x))
      translateY(var(--pos-12-y)); }
}

@keyframes bull5 {
  0%   {
    transform:
      translateX(var(--pos-5-x))
      translateY(var(--pos-5-y)); }
  100% {
    transform:
      translateX(var(--pos-13-x))
      translateY(var(--pos-13-y)); }
}
@keyframes bull6 {
  0%   {
    transform:
      translateX(var(--pos-6-x))
      translateY(var(--pos-6-y)); }
  100% {
    transform:
      translateX(var(--pos-14-x))
      translateY(var(--pos-14-y)); }
}
@keyframes bull7 {
  0%   {
    transform:
      translateX(var(--pos-7-x))
      translateY(var(--pos-7-y)); }
  100% {
    transform:
      translateX(var(--pos-15-x))
      translateY(var(--pos-15-y)); }
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.