<div id="replace"></div>
<div id="add"></div>
<div id="accumulate"></div>
div {
  position: relative;
  width: var(--size);
  height: var(--size);
  border: 1.2vmin solid currentColor;
  border-radius: 20%;
  font-size: 3vmin;
  margin: 5vmin;
  color: hsl(var(--hue, 343), 95%,54%);
  
  --size: 20vmin;
}

.supported:nth-of-type(2) {
  --hue: 168
}

.supported:nth-of-type(3) {
  --hue: 188
}

div::before {
  content: attr(id);
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  text-align: center;
  transform: translateY(-5vmin);
}

div::after {
  content: ':)';
  font-size: 4em;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  transform: rotate(90deg);
}

body {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden;
  background: hsl(223, 80%, 12%);
  font-family: system-ui, -apple-system, 'Segoe UI', sans-serif;
}
*, *::before, *::after {
  box-sizing: border-box;
}

select {
  position: absolute;
  top: 1rem;
  display: none;
}

.supported select {
  display: initial;
}
const replace = document.getElementById('replace');
const add = document.getElementById('add');
const accumulate = document.getElementById('accumulate');

const scaleKeyframes = [
  {transform: 'scale(1)'},
  {transform: 'scale(1.4)'}
]
const scaleTiming = {
  duration: 2100,
  iterations: Infinity,
  direction: 'alternate',
  easing: 'ease-in-out'
}

const rotateKeyframes = [
  {transform: 'rotate(0deg)'},
  {transform: 'rotate(90deg)'}
]
const rotateTiming = {
  duration: 3000,
  iterations: Infinity,
  direction: 'alternate',
  easing: 'ease-in'
}
const rotateTiming2 = {
  duration: 3900,
  iterations: Infinity,
  direction: 'alternate',
  easing: 'ease-in'
}

const translateKeyframes = [
  {transform: 'translate(0px, 0px)'},
  {transform: 'translate(-100px, -100px)'}
]
const translateTiming = {
  duration: 1600,
  iterations: Infinity,
  direction: 'alternate',
  easing: 'ease-in'
}

replace.animate(scaleKeyframes, scaleTiming);
replace.animate(rotateKeyframes, rotateTiming);
replace.animate(translateKeyframes, translateTiming);
replace.animate(rotateKeyframes, rotateTiming2);

add.animate(
  scaleKeyframes,
  Object.assign({composite: 'add'}, scaleTiming));
let rotate = add.animate(
  rotateKeyframes,
  Object.assign({composite: 'add'}, rotateTiming));
add.animate(
  translateKeyframes,
  Object.assign({composite: 'add'}, translateTiming));
add.animate(
  rotateKeyframes,
  Object.assign({composite: 'add'}, rotateTiming2));

if (rotate.effect && rotate.effect.composite === 'add') {
  add.classList.add('supported');
}

accumulate.animate(
  scaleKeyframes,
  Object.assign({composite: 'accumulate'}, scaleTiming));
let rotateAccumulate = accumulate.animate(
  rotateKeyframes,
  Object.assign({composite: 'accumulate'}, rotateTiming));
accumulate.animate(
  translateKeyframes,
  Object.assign({composite: 'accumulate'}, translateTiming));
accumulate.animate(
  rotateKeyframes,
  Object.assign({composite: 'accumulate'}, rotateTiming2));

if (rotateAccumulate.effect && rotateAccumulate.effect.composite === 'accumulate') {
  accumulate.classList.add('supported');
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.