<button class="c-button c-button--purple" type="button">
  <div class="c-ripple js-ripple">
    <span class="c-ripple__circle"></span>
  </div>
  Material Design Ripple Effect
</button>

<hr class="o-divider">

<button class="c-button c-button--blue" type="button">
  <div class="c-ripple js-ripple">
    <span class="c-ripple__circle"></span>
  </div>
  Short Button
</button>

<hr class="o-divider">

<button class="c-button c-button--red" type="button">
  <div class="c-ripple js-ripple">
    <span class="c-ripple__circle"></span>
  </div>
  Long Button to Stress-Test Ripple Animation
</button>
*,
*:after,
*:before {
	box-sizing: border-box;  
}

html {
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}

body {
	background: #434A54;
  font-family: "Open Sans", "Arial", sans-serif;
  text-rendering: optimizeSpeed;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  padding: 50px 0;
}

/**
 * Object: Divider
 * --------------------------------------------------
 */

.o-divider {
  border: 0;
  margin: 20px;
  height: 1px;
  background: #656D78;
}

/**
 * Component: Button
 * --------------------------------------------------
 */

.c-button {
  -webkit-appearance: none;
  position: relative;
  display: inline-block;
  padding: 12px 24px;
  margin: 0;
  vertical-align: middle;
  overflow: visible;
  color: #fff;
  font: inherit;
  font-size: 14px;
  line-height: 20px;
  font-weight: 400;
  text-align: center;
  letter-spacing: 1px;
  background: transparent;
  border: 0;
  user-select: none;
  box-shadow: 2px 2px 0 0 darken(#434A54, 5%);
  transition: all 0.2s ease;
  &:hover,
  &:focus {
    outline: 0;
    text-decoration: none;
  }
  &:not(:disabled) {
    cursor: pointer;
  }
}

/**
 * Mixin: Button Modifier
 * --------------------------------------------------
 */

@mixin button-modifier($color, $class) {
  .c-button--#{$class} {
    background: $color;
    text-shadow: 2px 2px 0 darken($color, 10%);
    &:hover {
      background: darken($color, 5%);
    }
  }
};

/**
 * Component: Button
 * Modifier: Purple
 * --------------------------------------------------
 */

@include button-modifier(#967ADC, purple);

/**
 * Component: Button
 * Modifier: Blue
 * --------------------------------------------------
 */

@include button-modifier(#4A89DC, blue);

/**
 * Component: Button
 * Modifier: Red
 * --------------------------------------------------
 */

@include button-modifier(#E9573F, red);

/**
 * Utility: Ripple
 * --------------------------------------------------
 */

.c-ripple {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: transparent;
}

.c-ripple__circle {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  opacity: 0;
  width: 0;
  height: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .25);
  .c-ripple.is-active & {
    animation: a-ripple .4s ease-in;
  }
}

/**
 * Animation: Ripple
 * --------------------------------------------------
 */

@keyframes a-ripple {
  0% {
    opacity: 0;
  }
  25% {
    opacity: 1;
  }
  100% {
    width: 200%;
    padding-bottom: 200%;
    opacity: 0;
  }
}
View Compiled
;(function($, window, document, undefined) {

  'use strict';

  var $ripple = $('.js-ripple');

  $ripple.on('click.ui.ripple', function(e) {

    var $this = $(this);
    var $offset = $this.parent().offset();
    var $circle = $this.find('.c-ripple__circle');

    var x = e.pageX - $offset.left;
    var y = e.pageY - $offset.top;

    $circle.css({
      top: y + 'px',
      left: x + 'px'
    });

    $this.addClass('is-active');

  });

  $ripple.on('animationend webkitAnimationEnd oanimationend MSAnimationEnd', function(e) {
  	$(this).removeClass('is-active');
  });

})(jQuery, window, document);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js