What is Google Material Design?

Click to run embed content:
https://www.youtube.com/watch?v=Q8TXgCzxEnw&feature=youtu.be

Ripple Click Effect in Web

Material Design is indeed quite impressive. Its fresh style and smooth animations are very appealing. What attracts me most is its Ripple Click Effect. I was wondering whether this effect could be implemented with CSS and JavaScript. The answer, of course, is yes!

HOW?

As can be seen from the video above, when the user clicks a button, a brief ripple animation appears on top of the button. The ripple starts from the place where the user clicked, its radius spreads and grows from zero, and the color of the ripple gradually fades until it finally disappears.
How should this requirement be designed in web design?

Coordinates at the time of clicking

Getting the coordinates when the user clicks is not difficult. We can use JavaScript to directly call event.pageX and event.pageY to get the current mouse position.

Ripple

Implementing the ripple effect is a bit more troublesome. However, the ripple effect can actually be simplified into two parts:
  • gradually growing in size
  • is circular
We break it down into two parts, then use CSS to implement the effects of these two parts separately, and finally overlay them to achieve this ripple effect!
For the size increase, we can use the CSS3 animation's transform: scale(2) to implement it. As for the circular shape, it's very simple; we can use a block-level element to implement it, set its width and height to be equal, and then use border-radius: 100% to achieve the circular effect.

Combining the two together

The effect we need to achieve is to generate a ripple animation at that coordinate after clicking. The animation can use transform To achieve this, and for the position of the animation, we can flexibly use absolute positioning and relative positioning. The specific approach is as follows:
  1. At the beginning, hide or remove the ripple animation element.
  2. When the user clicks, insert the ripple animation element above the clicked element.
  3. Calculate what the width and height of the ripple animation element should be.
  4. Calculate the coordinates of the mouse at this moment.
  5. Calculate how much the position of the ripple animation element should be offset relative to the clicked element.
  6. Add an animation effect to the ripple animation element.

SHOW ME THE CODE

After all that rambling, the code speaks for itself:
<div class="demo">
	<h1>Ripple Click Effect</h1>
	<ul>
		<li><a>Dashboard</a></li>
		<li><a>My Account</a></li>
		<li><a>Direct Messages</a></li>
		<li><a>Chat Rooms</a></li>
		<li><a>Settings</a></li>
		<li><a>Logout</a></li>
	</ul>
</div>
The above is the HTML code. There's nothing special about it—just a very ordinary unordered list.
.demo {
	margin: 0;
    padding: 20px 0;
    background: #789;
}
.demo h1 {
    text-align: center;
    color: #FFF;
    text-shadow: 1px 2px 0 rgba(0,0,0,0.5);
}

.demo ul {
    margin: 0 auto;
    padding: 0;
    width: 250px;
    border-top: 5px solid #678;
    background: #FFF;
    box-shadow: 0 0 10px rgba(0,0,0,0.5);
}

.demo ul li {
    list-style-type: none; 
    
    /* 使用相对定位,目的是为了给波纹元素作为偏移参考。 */
    position: relative;
    
    /* 溢出部分隐藏起来,这样才能保证波纹元素无论如何变化都始终在该 li 元素里面。 */
    overflow: hidden;
}

.demo ul li a {

	/* 使用相对定位,目的是为了给波纹元素作为偏移参考。 */
    position: relative;
    
    /* 将按钮设置成块级元素。 */
    display: block;
    padding: 10px 30px;
    color: #789;
    
    /* 由于在HTML中我们没有设置 href 属性,故不会显示可点击的鼠标。设置该 CSS 规则使得强制显示可点击鼠标手势。 */
    cursor: pointer;
    
    /* 避免多次点击按钮之后浏览器自动选中按钮中的文字。 */
    user-select: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
}

.demo .ink {
	/* 使用绝对定位,使得波纹元素位于点击时的鼠标坐标。 */
    position: absolute;
    
    /* 设置成块级元素才能正确设置高度 */
    display: block;
    
    /* 设置成100%以实现圆形效果 */
    border-radius: 100%;
    
    /* 默认状态下缩小为0,相当于不显示出来。 */
    transform: scale(0);
    -ms-transform: scale(0);
    -webkit-transform: scale(0);
    
    background: rgba(100,100,100,0.4);
}

.demo .animate {
	/* 使用CSS3的动画效果来实现波纹动画 */
    -webkit-animation: ripple 0.4s linear;
    -moz-animation: ripple 0.4s linear;
}

@-webkit-keyframes ripple {
	/* 动画执行过程的一些变化。此处是将波纹元素的大小变为 250%,透明度变为0 */
    100% {
        transform: scale(2.5);
        -ms-transform: scale(2.5);
        -webkit-transform: scale(2.5);
        opacity: 0;
    }
}
The above is the CSS code. It contains the corresponding comments.
$('a', $('.demo')).on('click', function (event) {
    var parent = $(this).parent();
    
    if (parent.find('.ink').length === 0) {
    	// 当 li 元素里面尚没有波纹元素时,则插入一个新的波纹元素进去。
        parent.prepend($('<span>').addClass('ink'));
    }
    
    var ink = parent.find('.ink');
    
    // 每次点击之后先移除上一次的动画。即移除 animate 类。
    ink.removeClass('animate');
    
    if (!ink.width() && !ink.height()) {
    	// 当波纹元素尚未设置大小时,为波纹元素设置长度和宽度。其值大小为 li 元素高和宽的最大值。这样才能保证波纹动画执行的过程中能够覆盖整个按钮元素。
        var d = Math.max(parent.width(), parent.height());
        ink.css({
            width: d + 'px',
            height: d + 'px'
        });
    }
    
    
    // 计算波纹元素的位置
    var x = event.pageX - parent.offset().left - ink.width() / 2;
    var y = event.pageY - parent.offset().top - ink.height() / 2;
    
    // 设置波纹元素的位置,并且添加类,开始执行动画。
    ink.css({
        top: y + 'px',
        left: x + 'px'
    }).addClass('animate');
});
The above is the JavaScript code. The code for the entire project is very little, and it can easily be ported to other projects.

A few final words

The animations in Material Design are all excellent. Some web developers have already developed similar libraries, such as:
The effects achieved by these libraries are all excellent. I believe that before long, Material Design will begin to spread across the internet!

Reference