Pure CSS で Material Design ライクな Ripple Effect を作ってみた

phi phi on css

Material Design で使われてるアレです.
アレを CSS のみで実装してみました.

あくまでライクなので, クリックした位置からではなく ボタンの中心から Ripple Effect が表示されるようになっています.

Pure CSS でもクリックした位置から表示する方法知ってる方いたら教えて下さい.

Rusntant Demo

今回作ったデモです. クリックするとポワッとサークルが表示されます.

http://goo.gl/s0yI5A

Code

HTML

<a class='btn-ripple'>default</a>  
<a class='btn-ripple red'>red</a>  
<a class='btn-ripple green'>green</a>  
<a class='btn-ripple blue'>blue</a>  

CSS

.btn-ripple {
  position: relative;
  overflow: hidden;
  display: inline-block;
  padding: 0px 2rem;
  height: 36px;
  line-height: 36px;
  background-color: #888;

  border-radius: 4px;
  border: none;
  outline: none;

  font-size: 1.5rem;
  color: white;
  text-align: center;

  cursor: pointer;
}

.btn-ripple:after {
  content: '';
  position: absolute;
  margin: auto;
  width: 40px;
  height: 40px;
  left: 0px;
  right: 0px;
  top: 0px;
  bottom: 0px;
  background-color: rgba(255, 255, 255, 0.5);
  border-radius: 50%;
  opacity: 0;
  -webkit-transform: scale(2.5);
  -moz-transform: scale(2.5);
  transform: scale(2.5);
  transition: all 1s ease-out;;
}

.btn-ripple:active:after {
  opacity: 1.0;
  -webkit-transform: scale(1);
  -moz-transform: scale(1);
  transform: scale(1);
  transition: 0s;
}

.red {
  background-color: hsl(0, 80%, 60%);
}
.green {
  background-color: hsl(120, 60%, 60%);
}
.blue {
  background-color: hsl(220, 80%, 60%);
}

Flow

HTML は要素の classbtn-ripple を指定してるだけなので,
CSS 部分のみ Step 形式で実装の流れを説明していきます.

詳しい解説は更に下で行っています.

1. HTML と基本となる CSS を設定

今回作ったやつの元となる雛形です. HTML には btn-ripple クラスを指定したボタン用要素を追加して, CSS には簡単な reset style を当てています.

http://goo.gl/XCBDPI

2. CSS でボタンを作ろう

ボタンをデザインしていきます.

CSS で下記のように指定します.

.btn-ripple {
  position: relative;
  overflow: hidden;
  display: inline-block;
  padding: 0px 2rem;
  height: 36px;
  line-height: 36px;
  background-color: #888;

  border-radius: 4px;
  border: none;
  outline: none;

  font-size: 1.5rem;
  color: white;
  text-align: center;

  cursor: pointer;
}

まず, positionrelative を指定します. これで子供要素の基準位置がこの要素になります. これが次の step で活きます! overflow:hidden も同じく次の要素で活きます.

あとは見た目を整えるための指定になります.

http://goo.gl/ynpznw

3. :after 擬似要素で Ripple Effect を作ろう

次に .btn-ripple に対する :after 擬似要素を定義していきます.

.btn-ripple:after {
  content: '';
  position: absolute;
  margin: auto;
  width: 40px;
  height: 40px;
  left: 0px;
  right: 0px;
  top: 0px;
  bottom: 0px;
  background-color: rgba(255, 255, 255, 0.5);
  border-radius: 50%;
}

本題である Ripple Effect を作っていきます. これは :after 擬似要素をうまく使うことで簡単に実装することができます.

content'' として空要素を定義しています. さらに width, height, background-color で矩形を定義し, border-radius:50% で円形にしています.

また, positionabsolute を指定し, left, right, top, botoom0px とすることでボタン中央に表示するようにしています.

親要素(.btn-ripple)で overflow:hidden を指定しているので, はみ出た部分は隠れる形で円形が表示されているのがわかるかと思います.

http://goo.gl/8r9nsM

4. アニメーションさせよう

クリックしたときのみ Ripple Effect が出て, かつアニメーションするように しましょう.

3 で定義した .btn-ripple:after に下記を追加します.

.btn-ripple:after {
  ...
  opacity: 0;
  -webkit-transform: scale(2.5);
  -moz-transform: scale(2.5);
  transform: scale(2.5);
  transition: all 1s ease-out;
}

これでまず, Ripple Effect が非表示になります.

そして次に :active 擬似クラスを使ってアクティブ状態のスタイルを定義します.

.btn-ripple:active:after {
  opacity: 1.0;
  -webkit-transform: scale(1);
  -moz-transform: scale(1);
  transform: scale(1);
  transition: 0s;
}

これでアクティブになったら opacity が 1 になるので クリック時のみ Rippple Effect が表示されるようになります.

http://goo.gl/s0yI5A

Tips

それぞれエントリー化しています.

親要素の中央に要素を表示する方法

:after 擬似要素とは?

:active 擬似クラスとは?