Recipe 8.1

Applying a Ripple Effect on Click

Animate an element by calling its animate method, passing a set of keyframes and options. Keyframes can be specified as an array of objects containing CSS properties to animate.

You can use the click location to set the position of the ripple element, then animate its scale and opacity.

Demo

Code

JavaScript
const button = document.querySelector('#button');

button.addEventListener('click', async event => {
  // Create the temporary element for the ripple, set its class, and
  // add it to the button.
  const ripple = document.createElement('div');
  ripple.className = 'ripple';

  // Find the largest dimension (width or height) of the button, and
  // use that as the ripple's size.
  const rippleSize = Math.max(button.offsetWidth, button.offsetHeight);
  ripple.style.width = `${rippleSize}px`;
  ripple.style.height = `${rippleSize}px`;

  // Center the ripple element on the click location.
  ripple.style.top = `${event.offsetY - (rippleSize / 2)}px`;
  ripple.style.left = `${event.offsetX - (rippleSize / 2)}px`;

  button.appendChild(ripple);
  
  // Perform the ripple animation, and wait for it to complete.
  await ripple.animate([
    { transform: 'scale(0)', opacity: 0.5 },
    { transform: 'scale(2.5)', opacity: 0 }
  ], {
    duration: 500,
    easing: 'ease-in'
  }).finished;

  // All done, remove the ripple element
  ripple.remove();
});
HTML
<style>
  #button {
    position: relative;
    overflow: hidden;
  }

  .ripple {
    background: white;
    pointer-events: none;
    transform-origin: center;
    opacity: 0;
    position: absolute;
    border-radius: 50%;
  }
</style>

<button id="button" class="fs-4 btn btn-primary">
  Click me!
</button>
Web API Cookbook
Joe Attardi