button
  svg(xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor")
    path(stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z")
View Compiled
:root {
  --base: #55b9f3;
  --lighten: #62d5ff;
  --darken: #489dcf;
  --white: #c8deeb;
  --shadow: 6px 6px 12px var(--darken), -6px -6px 12px var(--lighten);
  --inset: inset 6px 6px 12px var(--darken), inset -6px -6px 12px var(--lighten);
}

body {
  position: relative;
  width: 100vw;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--base);
  overflow: hidden;
}

button {
  z-index: 10;
  position: absolute;
  width: 40px;
  height: 40px;
  background-color: var(--base);
  color: var(--white);
  border: none;
  border-radius: 50%;
  box-shadow: var(--shadow);
  cursor: pointer;
}

svg {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

button.clicked {
  animation: shadowFadeOut 200ms ease-out forwards,
    shadowFadeIn 200ms 300ms ease-in forwards;
}

button.clicked svg {
  animation: fillFadeOut 200ms ease-out forwards,
    fillFadeIn 200ms 300ms ease-in forwards;
}

.wave {
  z-index: 1;
  position: absolute;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  box-shadow: 20px 20px 60px var(--darken), -20px -20px 60px var(--lighten);
  opacity: 0;
  animation: fadeIn 400ms ease-out forwards, outside_grow 5s ease-out,
    fadeOut 3s 2s forwards;
}

.wave::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 0px;
  height: 0px;
  border-radius: 50%;
  box-shadow: inset 20px 20px 60px var(--darken), inset -20px -20px 60px var(--lighten);
  animation: inside_grow 5s ease-out;
}

/** One of my worst keyframes, animate width & height.. */
@keyframes outside_grow {
  from {
    width: 20px;
    height: 20px;
  }
  to {
    width: 900px;
    height: 900px;
  }
}

/** This one is ugly too */
@keyframes inside_grow {
  from {
    width: 0px;
    height: 0px;
  }
  to {
    width: 880px;
    height: 880px;
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes fadeOut {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}

@keyframes shadowFadeIn {
  0% {
    box-shadow: var(--inset);
  }
  50% {
    box-shadow: none;
  }
  100% {
    box-shadow: var(--shadow);
  }
}

@keyframes shadowFadeOut {
  0% {
    box-shadow: var(--shadow);
  }
  50% {
    box-shadow: none;
  }
  100% {
    box-shadow: var(--inset);
  }
}

@keyframes fillFadeOut {
  from {
    fill: none;
  }
  to {
    fill: currentColor;
  }
}

@keyframes fillFadeIn {
  from {
    fill: currentcolor;
  }
  to {
    fill: none;
  }
}
const $button = document.querySelector("button");

let debounce = false;
$button.addEventListener("click", () => {
  if (debounce) return;
  debounce = true;
  buttonAnimate();
  createWave();
});

const buttonAnimate = () => {
  $button.classList.add("clicked");
  setTimeout(() => {
    $button.classList.remove("clicked");
    debounce = false;
  }, 700);
};

const createWave = () => {
  const wave = document.createElement("div");
  wave.classList.add("wave");
  document.body.appendChild(wave);
  setTimeout(() => wave.remove(), 7000);
};

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.