Material Design Type Ripple

Short script to make ripple when clicking on element

The ripple effect in UI became popular after Google released its Material Design guidelines. In practise it looks like an ink-drop that moves out radially from the position when the user taps or clips. In the sandbox below, you can find an example of how to recreate it. It is very light in terms of code and easy to use: all you have to do is add class=”ripple” to any element where you want the effect to be applied.

How it was made

Whenever you click on an element with class="ripple", you trigger a javascript function that does the following:

  • Creates a drop;
  • Positions the drop in the place where you clicked and sets its dimensions;
  • Removes the drop.

While Javascript only creates and positions the drop element, its animation is done with CSS. When the drop appears it is scaled to 0 with the help of the CSS transform property. Then the CSS @keyframe rule starts to animate the drop’s transform property to scale(2.2) and opacity to 0. By the end of the CSS animation, the drop is removed by Javascript.

Note that the ripple effect can only be applied to elements that can have the <span> element inside. You can not apply it, for example, to <input> or <tr> elements. Also, every element with class=”ripple” has overflow: hidden and position: relative CSS rules, so it might break the element in some cases. If you want to change the color or opacity of the ripple, just find .drop in CSS and adjust its background.

All fields below are editable. You can experiment with the code and see the result instantly:
<div class="container">
<div class="card">
<a href="javascript:;" onclick="return false;" class="button ripple">Button</a>
</div>
</div>
HTML
* {
box-sizing:border-box;
margin: 0;
padding: 0;
}

@import url('https://fonts.googleapis.com/css?family=Roboto+Condensed');

body {
background: #e2e2e2;
text-align: center;
}

.card {
background: #fff;
border-radius: 2px;
display: inline-block;
margin: 20px;
padding: 20px;
max-width: 300px;
width:100%;
box-shadow: 0 1px 3px rgba(0,0,0,0.15), 0 1px 2px rgba(0,0,0,0.25);
}

.button {
font-family: 'Roboto Condensed', sans-serif;
background: #0073c4;
color: #fff;
box-shadow: 0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12);
border: none;
border-radius: 2px;
height: 36px;
margin: 0;
padding: 0 16px;
display: inline-block;
font-size: 14px;
text-transform: uppercase;
outline: none;
cursor: pointer;
text-decoration: none;
text-align: center;
line-height: 36px;
vertical-align: middle;
}

.button:hover {
opacity: 0.9;
}

/* Ripple */
.ripple {
position: relative;
overflow: hidden;
-webkit-transform: translatez(0);
}

.drop {
display: block;
position: absolute;
background: rgba(0,0,0,0.20);
border-radius: 100%;
transform: scale(0);
pointer-events: none;
animation: ripple .7s ease-out;
}

@keyframes ripple {
to {
transform: scale(2.2);
opacity: 0;
}
}
CSS
(function($) {
$(".ripple").click(function(e){
var ripple = $(this),
drop = $('<span class="drop"></span>').appendTo(ripple),
d = Math.max(ripple.outerWidth(), ripple.outerHeight()),
x = e.pageX - ripple.offset().left - d/2,
y = e.pageY - ripple.offset().top - d/2;

drop.css({ height:d,width:d,top:y,left:x });
drop.one('animationend webkitAnimationEnd oanimationend MSAnimationEnd', function(e) {
drop.remove();
});
})
})(jQuery);
JavaScript/jQuery 1.x
Plugins used:
jQuery Apache 2.0
Browser support:
           
10+