波紋が広がるリップルエフェクトボタンの作り方(CSS・Javascript)

リップルエフェクトボタンの作り方

ボタンをクリックやタップしたときに「波紋のように広がる表現」をよく見かけるようになりました。このアニメーションはRipple Effect(リップルエフェクト)と呼ばれます。

フラットボタンへのリップルエフェクト

マテリアルデザインといえばリップルエフェクト

google trips

リップルエフェクトの例リップルエフェクトは、Googleが2014年〜提唱しているマテリアルデザインでよく使われます。インクの上に触れたような動きがとても美しいのですよね。この記事ではCSSJavascriptを使ってリップルエフェクトを実装する方法を解説します(jQueryは使いません)。

サンプル

今回の記事で紹介するサンプルです。是非タップしてみてください。なお、他の形でも簡単に実装することができます。

実装方法

この記事で紹介するエフェクトは以下のような流れで実装することができます。

大まかな流れ

  1. 紹介するCSSとJavascriptのコードをコピー
  2. コードを自由にアレンジしてペースト
  3. エフェクトをつけたい要素のクラス名にrippleを追加

もちろんクラス名を変えたり、コードの一部をコピーして使ってもOKです。早速やっていきましょう。

1. コード

CSS
.ripple {
	position: relative;
	overflow: hidden;
}

.ripple .rp-effect {/*エフェクト*/
	position: absolute;
	border-radius: 50%;
	opacity: 0.35;/*波紋の濃さ*/
	transform: scale(0);
	background: #FFF;/*波紋色*/
	animation: ripple 700ms;
	pointer-events: none; 
}

@-webkit-keyframes ripple {
  to {
    opacity: 0;
    transform: scale(2.0);
  }
}

@keyframes ripple {
  to {
    opacity: 0;
    transform: scale(2.0);
  }
}
Javascript
(function() {
	var ripple, ripples, RippleEffect,loc, cover, coversize, style, x, y, i, num;
	
	//クラス名rippleの要素を取得
	ripples = document.querySelectorAll('.ripple');

	//位置を取得
	RippleEffect = function(e) {
	ripple = this;//クリックされたボタンを取得
 	cover = document.createElement('span');//span作る
 	coversize = ripple.offsetWidth;//要素の幅を取得
	loc = ripple.getBoundingClientRect();//絶対座標の取得
	x = e.pageX - loc.left - window.pageXOffset - (coversize / 2);
	y = e.pageY - loc.top - window.pageYOffset - (coversize / 2);
	pos = 'top:' + y + 'px; left:' + x + 'px; height:' + coversize + 'px; width:' + coversize + 'px;';

	//spanを追加
	ripple.appendChild(cover);
	cover.setAttribute('style', pos);
	cover.setAttribute('class', 'rp-effect');//クラス名追加
	
	//しばらくしたらspanを削除
	setTimeout(function() {
		var list = document.getElementsByClassName( "rp-effect" ) ;
		for(var i =list.length-1;i>=0; i--){//末尾から順にすべて削除
    	list[i].parentNode.removeChild(list[i]);
	}}, 2000)};
	for (i = 0, num = ripples.length; i < num; i++) {
		ripple = ripples[i];
		ripple.addEventListener('mousedown', RippleEffect);
	}
}());

Javascriptは外部ファイルで読み込んでも良いですし、<script>〜</script>ではさんで、</body>の直前に貼ってもOKです。

解説

まず大まかなイメージを説明します。クラス名がrippleの要素をクリックすると、Javascriptによりspanタグが追加されます。このspan要素がボタンの上で波紋のように広がっていきます。広がる動き自体はCSSにより表現されています。

サルワカくんの顔(通常)
サルワカくん

「CSSだけでできないの?」と疑問に思うかもしれませんが、Javascriptによりクリックした位置を取得して、そこを中心にリップルエフェクトをかけることができます。CSSだけでは「クリックしたところから波紋を広げる」ことができません。

▼ spanは削除する追加されたspan要素はそのままでも良いのですが、念のためしばらくすると消えるよう指定してあります。

▼ 絶対座標の位置(読み飛ばしてOK) y = e.pageY - loc.top....のあたりが非常に複雑になっています。これは親要素(=ボタン)に対するspanの位置を指定するためのものです。e.pageXはクリックした部分の絶対位置、loc.topは親要素の位置を出力しています。この2つを引き算することで、spanタグのtop:◯◯の値をだいたい算出できます。 window.pageYOffsetはスクロールしたときのズレを防ぐもの、coversize / 2はspanの中心=クリック部分となるようにするための微調整です。

2. アレンジ

波紋の透明度を変える

CSSの.ripple .rp-effect{〜}のうちopacity: 0.35の値を大きくすると波紋が濃くなります(1.0が最大値です)。逆に小さくすると薄くなります。

色を変える

上のコードでは白(background: #FFF)のリップルエフェクトがかかります。カラフルな色コードを指定することもできます。

エフェクトのスピードを変える

animation: ripple 700msの700の数字を小さくすれば、広がるスピードが早くなります。大きくすればゆっくりと広がるようになります。

3. コードを貼り付け

例えば、こちらのボタンにリップルエフェクトがかかるようにしてみましょう。

▼ リップルエフェクト無しの状態

HTML
<a class="raised" href="#">BUTTON</a>
CSS
.raised{
	display: inline-block;
	background-color: #26a69b;
	color: #FFF;
	font-size: 1em;
	text-decoration: none;
	letter-spacing: 0.05em;
	padding: 0.6em 1.3em;
	border-radius: 2px;
	cursor: pointer;
	box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 1px 5px 0 rgba(0,0,0,0.12), 0 3px 1px -2px rgba(0,0,0,0.2);
	-webkit-tap-highlight-color: transparent;
	transition: .3s;
}
.raised:hover{
	box-shadow: 0 3px 3px 0 rgba(0,0,0,0.14), 0 1px 7px 0 rgba(0,0,0,0.12), 0 3px 1px -1px rgba(0,0,0,0.2);
}

このボタン(aタグ)にクラス名rippleを追加し、さきほどのCSSとJavascriptのコードを加えます。

▼ リップルエフェクトをつけた場合

HTML
<a href="#" class="raised ripple">BUTTON</a>
CSS
.raised{〜略〜}
.raised:hover{〜略〜}

.ripple {〜略〜}
.ripple .rp-effect{〜略〜}
@-keyframes ripple{〜略〜}
Javascript
(function() {〜略〜



BUTTON

↑クリックすると…


このようにクラス名にrippleを足すことで、リップルエフェクトをかけることができます。.ripple{〜}などの内容をボタンに対する元のCSS指定に追加しても良いですね。

コードサンプル

他にも様々なものに対してリップルエフェクトを実装することができます。

円形のボタン

マテリアルデザインらしいアイコンを使った円形のボタン(フローティング操作ボタン)です。


カーソルのホバーで色が変わり、クリックすると波紋が広がります。

HTML
<a href="#" id="fab" class="ripple">
     <i class="fa fa-share"></i>
</a>
CSS
#fab {
	display: block;
	width: 56px;
	height: 56px;
	background: #f45f5f;
	text-align: center;
	border-radius: 50%;
	transition: .2s;
	box-shadow: 0 2px 2px 0 rgba(0,0,0,.12), 0 2px 2px 0 rgba(0,0,0,.24);
}

#fab:hover{
	background:#ff7c7c;
}

#fab i {
	color: white;
	line-height: 56px;
	vertical-align: middle;
	font-size: 18px;
	transition: .3s;
}

#fab:hover {
	box-shadow: 0 4px 5px 0 rgba(0,0,0,.14), 0 1px 10px 0 rgba(0,0,0,.12), 0 2px 4px -1px rgba(0,0,0,.2);/*浮き上がる*/}

↑【注意】これに加えてさきほどのCSSとJavascriptのコードを書くことで、クリックによりリップルエフェクトがかかるボタンが出来上がります。

テキストボタン

フラットボタン

はじめは単純なテキストですがカーソルを当てると背景にうっすらと色がつき、クリックによりリップルエフェクトがかかります。本物のサンプルはこちら↓

BUTTON


コードは以下のように書きます。なお、波紋の色は白ではなくグレイにしてみました。

HTML
<a href="#" class="flat_button ripple">BUTTON</a>
CSS
.flat_button {
	display: inline-block;
	cursor:pointer;
	text-decoration: none;
	color:#555; /*文字色*/
	padding:0.4em 1.5em;
	transition: .5s;
}
.flat_button:hover {
	background: #EFEFEF;
}

.flat_button .rp-effect {
	background: gray;
}

↑【注意】これに加えてさきほどのCSSとJavascriptのコードを書いて完成です。

ブラウザ対応状況

上で紹介した実装のブラウザ対応状況にも触れておきます。ネックとなるのはCSSアニメーション(@keyframes)です。IE9以下はCSSアニメーションに対応していないので注意が必要です。とはいえ2017年3月現在、グローバルに見た使用ブラウザのうち約95%は問題なく対応しているようです(参考:CANIUSE)。また、対応していないブラウザでもボタンは問題なく機能するため、気にせず使ってしまっても良いのではないかと思います。

参考

マテリアルデザインの作り方については以下の記事でまとめています。

 
サルワカ