CSSで実装するハンバーガーメニュークリック時のエフェクト 10+

Tips

CSSで実装するハンバーガーメニュークリック時のエフェクト 10+

自分用に一覧化したのでシェアします。
ハンバーガーメニューは「メニューだとわかりづらい」と言われることも多いですが、特にスマートフォンサイトなどでは実装する機会はやはり多くはなってきているので、今回はそのハンバーガーメニューをクリックした時(メニューが展開している時などのアクティブ時)のエフェクトをCSSで実装したサンプルをまとめました。
よく見る「×」のようなクローズボタンに変化するものから矢印に変化するものまで全12種類あります。

January 21, 2016 追記

以下では紹介していないエフェクトを「CSSで実装するハンバーガーメニューアイコンの見栄えやクリック・ホバー時のエフェクト 10」で紹介しているので、興味ある方はこちらも併せてご覧ください。
少しですが、クリック時以外にホバー時のエフェクトなども紹介しています。

共通のHTML・CSS

ハンバーガーメニューをHTMLとCSSで表現しようとした場合、擬似要素を用いることで要素ひとつで実装したり、input要素を使って実装したりといろいろな方法を見かけますが、今回のサンプルではそれぞれのラインがどのような動きをしているかわかりやすいと思ったので、いずれも下記のようにa要素とspan要素を用いたHTMLを使用しています。

HTML

<a class="menu-trigger" href="#">
  <span></span>
  <span></span>
  <span></span>
</a>

CSSについては下記を共通スタイルとして指定しており、ライン部分は空のspan要素にwidthheightbackground-colorなどを組み合わせて見栄えを作っています。
幅や高さを指定している部分もあるので、参考にされる際はこれらを自身の環境に合わせて調整してください。

CSS

.menu-trigger,
.menu-trigger span {
  display: inline-block;
  transition: all .4s;
  box-sizing: border-box;
}
.menu-trigger {
  position: relative;
  width: 50px;
  height: 44px;
}
.menu-trigger span {
  position: absolute;
  left: 0;
  width: 100%;
  height: 4px;
  background-color: #fff;
  border-radius: 4px;
}
.menu-trigger span:nth-of-type(1) {
  top: 0;
}
.menu-trigger span:nth-of-type(2) {
  top: 20px;
}
.menu-trigger span:nth-of-type(3) {
  bottom: 0;
}

※閲覧の際にChrome又はFirefoxで見てもらえるとほぼ問題なく動きの確認ができると思いますが、ブラウザによって動きや見栄えが説明と異なる場合があります。

※メニュークリック時に関してはjQueryの.toggleClass()を使ってactiveというクラスが付加する動きを以下のサンプルでは実装していますので、それぞれサンプルのCSSもクリック後に.activeというクラスが付加される場合の記述となっています。

CSSで実装するハンバーガーメニュークリック時のエフェクト 10+ 目次

  1. 中央のラインが消え、上下のラインでクローズボタンに
  2. 中央のラインが消え、上下のラインが回転しながらクローズボタンに
  3. メニュー全体が回転しながらクローズボタンに #1
  4. メニュー全体が回転しながらクローズボタンに #2
  5. 中央ラインの位置がずれながら消えていく
  6. 中央ラインが飛んでいく
  7. ラインがひとつになり、その後クローズボタンに
  8. 上下のラインを動かして矢印に
  9. 回転しながら矢印に
  10. メニューボタンの向きを変える
  11. クローズボタン変形前に波紋エフェクトを加える
  12. 中央ラインがサークルに変形するような見た目

1. 中央のラインが消え、上下のラインでクローズボタンに

クリックすると中央のラインがフェードアウトし、上下のラインがそれぞれ傾きクローズボタンになるものです。
クリック後のスタイルとしてCSSに下記を記述します。

CSS

.menu-trigger.active span:nth-of-type(1) {
  -webkit-transform: translateY(20px) rotate(-45deg);
  transform: translateY(20px) rotate(-45deg);
}
.menu-trigger.active span:nth-of-type(2) {
  opacity: 0;
}
.menu-trigger.active span:nth-of-type(3) {
  -webkit-transform: translateY(-20px) rotate(45deg);
  transform: translateY(-20px) rotate(45deg);
}

目次へ

2. 中央のラインが消え、上下のラインが回転しながらクローズボタンに

先ほどと同様にクリックすると中央のラインがフェードアウトし、上下のラインがそれぞれ傾きクローズボタンになるものですが、rotateの値を大きくすることでクルッと回転しながらクローズボタンの見栄えになる動きにできます。
クリック後のスタイルとしてCSSに下記を記述します。

CSS

.menu-trigger.active span:nth-of-type(1) {
  -webkit-transform: translateY(20px) rotate(-315deg);
  transform: translateY(20px) rotate(-315deg);
}
.menu-trigger.active span:nth-of-type(2) {
  opacity: 0;
}
.menu-trigger.active span:nth-of-type(3) {
  -webkit-transform: translateY(-20px) rotate(315deg);
  transform: translateY(-20px) rotate(315deg);
}

目次へ

3. メニュー全体が回転しながらクローズボタンに #1

上で紹介してきたものと同じような感じでクリックするとひとつだけラインが消えて残りふたつのラインを傾けるという記述をしつつ、そこへ更にメニュー自体も回転するような記述を加えたものです。
クリック後のスタイルとしてCSSに下記を記述します。

CSS

.menu-trigger.active {
  -webkit-transform: rotate(360deg);
  transform: rotate(360deg);
}
.menu-trigger.active span:nth-of-type(1) {
  -webkit-transform: translateY(20px) rotate(-45deg);
  transform: translateY(20px) rotate(-45deg);
}
.menu-trigger.active span:nth-of-type(2) {
  -webkit-transform: translateY(0) rotate(45deg);
  transform: translateY(0) rotate(45deg);
}
.menu-trigger.active span:nth-of-type(3) {
  opacity: 0;
}

目次へ

4. メニュー全体が回転しながらクローズボタンに #2

先ほどと同様にメニュー全体が回転するものですが、こちらはtransform: rotateXを使ったタイプで、クリック後のスタイルとしてCSSに下記を記述します。

CSS

.menu-trigger span:nth-of-type(3),
.menu-trigger.active span:nth-of-type(3) {
  transition: none;
}
.menu-trigger.active {
  -webkit-transform: rotateX(720deg);
  transform: rotateX(720deg);
}
.menu-trigger.active span:nth-of-type(1) {
  -webkit-transform: translateY(20px) rotate(-45deg);
  transform: translateY(20px) rotate(-45deg);
}
.menu-trigger.active span:nth-of-type(2) {
  -webkit-transform: translateY(0) rotate(45deg);
  transform: translateY(0) rotate(45deg);
}
.menu-trigger.active span:nth-of-type(3) {
  opacity: 0;
}

※iPhoneでmobile safariで確認する際にメニューが消えてしまう場合は、その親となる要素にCSSでperspectiveを指定することで消えてしまうのを回避できます。

目次へ

5. 中央ラインの位置がずれながら消えていく

基本的には「1. 中央のラインが消え、上下のラインでクローズボタンに」の動きと同じですが、そこへ更に中央ライン位置が横にずれる動きを加えたものです。
サンプルは中央のラインが右にずれながら消えるというもので、クリック後のスタイルとしてCSSに下記を記述します。

CSS

.menu-trigger.active span:nth-of-type(1) {
  -webkit-transform: translateY(20px) rotate(-45deg);
  transform: translateY(20px) rotate(-45deg);
}
.menu-trigger.active span:nth-of-type(2) {
  left: 50%;
  opacity: 0;
  -webkit-animation: active-menu-bar02 .8s forwards;
  animation: active-menu-bar02 .8s forwards;
}
@-webkit-keyframes active-menu-bar02 {
  100% {
    height: 0;
  }
}
@keyframes active-menu-bar02 {
  100% {
    height: 0;
  }
}
.menu-trigger.active span:nth-of-type(3) {
  -webkit-transform: translateY(-20px) rotate(45deg);
  transform: translateY(-20px) rotate(45deg);
}

※上記では消えていく中央ラインがクリックできるのを防ぐためにspan:nth-of-type(2)の動きの一部にanimationを用いていますが、Chromeであればanimationを使用せずにz-index: -1を記述すれば同じ見た目を実装できます。

目次へ

6. 中央ラインが飛んでいく

基本的な動きは「5. 中央ラインの位置がずれながら消えていく」の動きと同じ中央ライン位置が横にずれる動きになりますが、それを少しいじって飛んでいくような動きにしたものです。
クリック後のスタイルとしてCSSに下記を記述します。

CSS

.menu-trigger.active span:nth-of-type(1) {
  -webkit-transform: translateY(20px) rotate(-45deg);
  transform: translateY(20px) rotate(-45deg);
}
.menu-trigger.active span:nth-of-type(2) {
  left: 200%;
  opacity: 0;
  -webkit-transform: translateY(10px);
  transform: translateY(10px);
  -webkit-animation: active-menu-bar02 .8s forwards;
  animation: active-menu-bar02 .8s forwards;
}
@-webkit-keyframes active-menu-bar02 {
  100% {
    height: 0;
  }
}
@keyframes active-menu-bar02 {
  100% {
    height: 0;
  }
}
.menu-trigger.active span:nth-of-type(3) {
  -webkit-transform: translateY(-20px) rotate(45deg);
  transform: translateY(-20px) rotate(45deg);
}

※上記では消えていく中央ラインがクリックできるのを防ぐためにspan:nth-of-type(2)の動きの一部にanimationを用いていますが、Chromeであればanimationを使用せずにz-index: -1を記述すれば同じ見た目を実装できます。

目次へ

7. ラインがひとつになり、その後クローズボタンに

クリックするとまず上下のラインが中央に移動して見た目がひとつのラインになり、その後クローズボタンに変化するというものです。
実装には共通のスタイルに加え、CSSに下記を記述します。

CSS

.menu-trigger span:nth-of-type(1) {
  -webkit-animation: menu-bar01 .75s forwards;
  animation: menu-bar01 .75s forwards;
}
@-webkit-keyframes menu-bar01 {
  0% {
    -webkit-transform: translateY(20px) rotate(45deg);
  }
  50% {
    -webkit-transform: translateY(20px) rotate(0);
  }
  100% {
    -webkit-transform: translateY(0) rotate(0);
  }
}
@keyframes menu-bar01 {
  0% {
    transform: translateY(20px) rotate(45deg);
  }
  50% {
    transform: translateY(20px) rotate(0);
  }
  100% {
    transform: translateY(0) rotate(0);
  }
}
.menu-trigger span:nth-of-type(2) {
  transition: all .25s .25s;
  opacity: 1;
}
.menu-trigger span:nth-of-type(3) {
  -webkit-animation: menu-bar02 .75s forwards;
  animation: menu-bar02 .75s forwards;
}
@-webkit-keyframes menu-bar02 {
  0% {
    -webkit-transform: translateY(-20px) rotate(-45deg);
  }
  50% {
    -webkit-transform: translateY(-20px) rotate(0);
  }
  100% {
    -webkit-transform: translateY(0) rotate(0);
  }
}
@keyframes menu-bar02 {
  0% {
    transform: translateY(-20px) rotate(-45deg);
  }
  50% {
    transform: translateY(-20px) rotate(0);
  }
  100% {
    transform: translateY(0) rotate(0);
  }
}
.menu-trigger.active span:nth-of-type(1) {
  -webkit-animation: active-menu-bar01 .75s forwards;
  animation: active-menu-bar01 .75s forwards;
}
@-webkit-keyframes active-menu-bar01 {
  0% {
    -webkit-transform: translateY(0) rotate(0);
  }
  50% {
    -webkit-transform: translateY(20px) rotate(0);
  }
  100% {
    -webkit-transform: translateY(20px) rotate(45deg);
  }
}
@keyframes active-menu-bar01 {
  0% {
    transform: translateY(0) rotate(0);
  }
  50% {
    transform: translateY(20px) rotate(0);
  }
  100% {
    transform: translateY(20px) rotate(45deg);
  }
}
.menu-trigger.active span:nth-of-type(2) {
  opacity: 0;
}
.menu-trigger.active span:nth-of-type(3) {
  -webkit-animation: active-menu-bar03 .75s forwards;
  animation: active-menu-bar03 .75s forwards;
}
@-webkit-keyframes active-menu-bar03 {
  0% {
    -webkit-transform: translateY(0) rotate(0);
  }
  50% {
    -webkit-transform: translateY(-20px) rotate(0);
  }
  100% {
    -webkit-transform: translateY(-20px) rotate(-45deg);
  }
}
@keyframes active-menu-bar03 {
  0% {
    transform: translateY(0) rotate(0);
  }
  50% {
    transform: translateY(-20px) rotate(0);
  }
  100% {
    transform: translateY(-20px) rotate(-45deg);
  }
}

目次へ

8. 上下のラインを動かして矢印に

横からスライドしてくるナビゲーションを実装しているサイトなどで見かけることがある、ハンバーガーから矢印へと変化するものです。
クリック後のスタイルとしてCSSに下記を記述します。

CSS

.menu-trigger.active span:nth-of-type(1),
.menu-trigger.active span:nth-of-type(3) {
  width: 20px;
}
.menu-trigger.active span:nth-of-type(1) {
  -webkit-transform: translate(-1px,13px) rotate(-45deg);
  transform: translate(-1px,13px) rotate(-45deg);
}
.menu-trigger.active span:nth-of-type(3) {
  -webkit-transform: translate(-1px,-13px) rotate(45deg);
  transform: translate(-1px,-13px) rotate(45deg);
}

目次へ

9. 回転しながら矢印に

先ほどのハンバーガーから矢印へと変化するものに回転の動きを加えたものです。
記述もほぼ同じで、クリック後のスタイルとしてCSSに下記を記述します。

CSS

.menu-trigger.active {
  -webkit-transform: rotate(360deg);
  transform: rotate(360deg);
}
.menu-trigger.active span:nth-of-type(1),
.menu-trigger.active span:nth-of-type(3) {
  width: 20px;
}
.menu-trigger.active span:nth-of-type(1) {
  -webkit-transform: translate(-1px,13px) rotate(-45deg);
  transform: translate(-1px,13px) rotate(-45deg);
}
.menu-trigger.active span:nth-of-type(3) {
  -webkit-transform: translate(-1px,-13px) rotate(45deg);
  transform: translate(-1px,-13px) rotate(45deg);
}

目次へ

10. メニューボタンの向きを変える

こちらはクローズボタンや矢印になるものではなく、たまに実装しているサイトを見かけることもあるボタンが縦向きに変更するものです。
クリック後のスタイルとしてCSSに下記を記述し、見ての通りtransform: rotateで90度回転させるだけです。

CSS

.menu-trigger.active {
  -webkit-transform: rotate(90deg);
  transform: rotate(90deg);
}

目次へ

11. クローズボタン変形前に波紋エフェクトを加える

基本的には「1. 中央のラインが消え、上下のラインでクローズボタンに」の動きと同じですが、その動きの前に波紋のようなエフェクトを加えたものです。
実装には共通のスタイルに加え、CSSに下記を記述します。

CSS

.menu-trigger span:nth-of-type(1) {
  -webkit-animation: menu-bar01 .5s forwards;
  animation: menu-bar01 .5s forwards;
}
@-webkit-keyframes menu-bar01 {
  0% {
    -webkit-transform: translateY(20px) rotate(-45deg);
  }
  100% {
    -webkit-transform: translateY(0) rotate(0);
  }
}
@keyframes menu-bar01 {
  0% {
    transform: translateY(20px) rotate(-45deg);
  }
  100% {
    transform: translateY(0) rotate(0);
  }
}
.menu-trigger span:nth-of-type(2) {
  -webkit-animation: menu-bar02 .5s forwards;
  animation: menu-bar02 .5s forwards;
}
@-webkit-keyframes menu-bar02 {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
@keyframes menu-bar02 {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
.menu-trigger span:nth-of-type(3) {
  -webkit-animation: menu-bar03 .5s forwards;
  animation: menu-bar03 .5s forwards;
}
@-webkit-keyframes menu-bar03 {
  0% {
    -webkit-transform: translateY(-20px) rotate(45deg);
  }
  100% {
    -webkit-transform: translateY(0) rotate(0);
  }
}
@keyframes menu-bar03 {
  0% {
    transform: translateY(-20px) rotate(45deg);
  }
  100% {
    transform: translateY(0) rotate(0);
  }
}
.menu-trigger::after {
  position: absolute;
  top: 50%;
  left: 50%;
  display: block;
  content: '';
  width: 30px;
  height: 30px;
  margin: -16px 0 0 -16px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,.3);
  transition: all .1s;
  opacity: 0;
}
.menu-trigger.active::after {
  -webkit-animation: circle .5s;
  animation: circle .5s;
}
@-webkit-keyframes circle {
  0% {
    -webkit-transform: scale(.1);
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  100% {
    -webkit-transform: scale(3.5);
    opacity: 0;
  }
}
@keyframes circle {
  0% {
    transform: scale(.1);
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  100% {
    transform: scale(3.5);
    opacity: 0;
  }
}
.menu-trigger.active span:nth-of-type(1) {
  -webkit-animation: active-menu-bar01 .5s .5s forwards;
  animation: active-menu-bar01 .5s .5s forwards;
}
@-webkit-keyframes active-menu-bar01 {
  0% {
    -webkit-transform: translateY(0) rotate(0);
  }
  100% {
    -webkit-transform: translateY(20px) rotate(-45deg);
  }
}
@keyframes active-menu-bar01 {
  0% {
    transform: translateY(0) rotate(0);
  }
  100% {
    transform: translateY(20px) rotate(-45deg);
  }
}
.menu-trigger.active span:nth-of-type(2) {
  -webkit-animation: active-menu-bar02 .5s .5s forwards;
  animation: active-menu-bar02 .5s .5s forwards;
}
@-webkit-keyframes active-menu-bar02 {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}
@keyframes active-menu-bar02 {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}
.menu-trigger.active span:nth-of-type(3) {
  -webkit-animation: active-menu-bar03 .5s .5s forwards;
  animation: active-menu-bar03 .5s .5s forwards;
}
@-webkit-keyframes active-menu-bar03 {
  0% {
    -webkit-transform: translateY(0) rotate(0);
  }
  100% {
    -webkit-transform: translateY(-20px) rotate(45deg);
  }
}
@keyframes active-menu-bar03 {
  0% {
    transform: translateY(0) rotate(0);
  }
  100% {
    transform: translateY(-20px) rotate(45deg);
  }
}

目次へ

12. 中央ラインがサークルに変形するような見た目

実際には同じ要素を使っているわけではないですが、「5. 中央ラインの位置がずれながら消えていく」の動きをしつつ、そこに擬似要素を使ってその中央ラインがサークルになっていくような見た目にしたものです。
実装には共通のスタイルに加え、CSSに下記を記述します。

CSS

.menu-trigger::after {
  position: absolute;
  top: 50%;
  left: 50%;
  display: block;
  content: '';
  width: 84px;
  height: 84px;
  margin: -45px 0 0 -45px;
  border-radius: 50%;
  border: 4px solid transparent;
  transition: all .75s;
}
.menu-trigger.active span:nth-of-type(1) {
  -webkit-transform: translateY(20px) rotate(-45deg);
  transform: translateY(20px) rotate(-45deg);
}
.menu-trigger.active span:nth-of-type(2) {
  left: 60%;
  opacity: 0;
  -webkit-animation: active-menu-bar02 .8s forwards;
  animation: active-menu-bar02 .8s forwards;
}
@-webkit-keyframes active-menu-bar02 {
  100% {
    height: 0;
  }
}
@keyframes active-menu-bar02 {
  100% {
    height: 0;
  }
}
.menu-trigger.active span:nth-of-type(3) {
  -webkit-transform: translateY(-20px) rotate(45deg);
  transform: translateY(-20px) rotate(45deg);
}
.menu-trigger.active::after {
  -webkit-animation: circle .4s .25s forwards;
  animation: circle .4s .25s forwards;
}
@-webkit-keyframes circle {
  0% {
    border-color: transparent;
    -webkit-transform: rotate(0);
  }
  25% {
    border-color: transparent #fff transparent transparent;
  }
  50% {
    border-color: transparent #fff #fff transparent;
  }
  75% {
    border-color: transparent #fff #fff #fff;
  }
  100% {
    border-color: #fff;
    -webkit-transform: rotate(-680deg);
  }
}
@keyframes circle {
  0% {
    border-color: transparent;
    transform: rotate(0);
  }
  25% {
    border-color: transparent #fff transparent transparent;
  }
  50% {
    border-color: transparent #fff #fff transparent;
  }
  75% {
    border-color: transparent #fff #fff #fff;
  }
  100% {
    border-color: #fff;
    transform: rotate(-680deg);
  }
}

サークルを表現するために擬似要素を作成し、まずはそこでborder-colortransparentを指定しておきます。
あとはクリック(クラスが付加)されたタイミングでそれぞれのborderにひとつずつカラー指定される動きをanimationで指定しつつtransform: rotateで回転させることでこのような見た目になります。
ちなみに今回はCSSだけで実装ということでこのようにborderを用いてやってみましたが、普通にサークル部分はSVG使ってやったりした方が全然綺麗に実装できます...。

目次へ

上で紹介した動きをまとめて確認したい場合は以下でご覧になれます。

Posted on

Category : Tips

Close the search window,
please press close button or esc key.