LoginSignup
33
39

More than 5 years have passed since last update.

三本線のメニューアイコンから×マークに変化するアニメーションいろいろ

Last updated at Posted at 2017-04-24

CSSでアニメーションができるわけですし、どうせならちょっとアクセントをつけたいって感じのやつです。

三本線から×に変化させる

いろいろアイデアありますね。

JavaScriptはクラス名を変更するためだけにちょろっと使ってるだけなのでシンプルです。
チェックボックスを活用したJavaScriptを完全に使わない方法もありますが割愛。

まず、以下のHTMLとCSSは共通で使用するものとします。

HTML
<div class="menuWrapper">
  <a href="#menu" id="menuButton"><span>MENU</span></a>
</div>
CSS
.menuWrapper {
  position: relative;
  z-index: 0;
  border: 1px solid #ccc;
  width: 50px;
  height: 50px;
}

#menuButton {
  overflow: hidden;
  display: block;
  position: relative;
  z-index: 0;
  width: 50px;
  height: 50px;
  cursor: pointer;
}

#menuButton span,
#menuButton::before,
#menuButton::after {
  display: block;
  position: absolute;
  top: 0;
  bottom: 0;
  left:0;
  right: 0;
  width: 36px;
  height: 4px;
  margin: auto;
  background: #000;
}
#menuButton span {
  overflow: hidden;
  z-index: 1;
  color: #000;
}
#menuButton::before {
  z-index: 2;
  transform: translate(0, -12px);
  content: "";
}
#menuButton::after {
  z-index: 2;
  transform: translate(0, 12px);
  content: "";
}

こんな感じの表示になります。

sample.png

サンプル1

sample1.gif

実際の動作サンプル1

CSS
#menuButton span {
  opacity: 1;
  transition: opacity 150ms 50ms;
}
#menuButton::before,
#menuButton::after {
  transition: transform 200ms;
}

#menuButton.active span {
  opacity: 0;
  transition: opacity 150ms;
}
#menuButton.active::before {
  transform: rotate(45deg);
}
#menuButton.active::after {
  transform: rotate(-45deg);
}
JavaScript
document.addEventListener('DOMContentLoaded', function () {
  document.getElementById('menuButton').addEventListener('click', function (ev) {
    ev.preventDefault();
    this.classList.toggle('active');
  });
});

サンプル2

sample2.gif

実際の動作サンプル2

CSS
#menuButton span {
  transition: transform 150ms 50ms;
}
#menuButton::before,
#menuButton::after {
  transition: transform 200ms;
}

#menuButton.active span {
  transform: translate(-50px, 0);
  transition: transform 150ms;
}
#menuButton.active::before {
  transform: rotate(45deg);
}
#menuButton.active::after {
  transform: rotate(-45deg);
}
JavaScript
document.addEventListener('DOMContentLoaded', function () {
  document.getElementById('menuButton').addEventListener('click', function (ev) {
    ev.preventDefault();
    this.classList.toggle('active');
  });
});

サンプル3

sample3.gif

実際の動作サンプル3

CSS
#menuButton {
  transition: transform 300ms;
}
#menuButton span {
  opacity: 1;
  transition: opacity 200ms;
}
#menuButton::before,
#menuButton::after {
  transition: transform 200ms;
}

#menuButton.active {
  transform: rotate(180deg);
}
#menuButton.active span {
  opacity: 0;
}
#menuButton.active::before {
  transform: rotate(45deg);
}
#menuButton.active::after {
  transform: rotate(-45deg);
}
JavaScript
document.addEventListener('DOMContentLoaded', function () {
  document.getElementById('menuButton').addEventListener('click', function (ev) {
    ev.preventDefault();
    this.classList.toggle('active');
  });
});

サンプル4

sample4.gif

実際の動作サンプル4

CSS
@keyframes lineTop {
  50% {
    transform: translate(0, 0);
  }
  100% {
    transform: rotate(45deg);
  }
}
@keyframes lineMiddle {
  50%, 100% {
    opacity: 0;
  }
}
@keyframes lineBottom {
  50% {
    transform: translate(0, 0);
  }
  100% {
    transform: rotate(-45deg);
  }
}

#menuButton.active span {
  animation: lineMiddle 250ms step-end forwards;
}
#menuButton.active::before {
  animation: lineTop 250ms forwards;
}
#menuButton.active::after {
  animation: lineBottom 250ms forwards;
}

#menuButton.default span {
  animation: lineMiddle 250ms step-end reverse;
}
#menuButton.default::before {
  animation: lineTop 250ms reverse;
}
#menuButton.default::after {
  animation: lineBottom 250ms reverse;
}
JavaScript
document.addEventListener('DOMContentLoaded', function () {
  document.getElementById('menuButton').addEventListener('click', function (ev) {
    var classList = this.classList;
    ev.preventDefault();
    if (classList.contains('active')) {
      classList.remove('active');
      requestAnimationFrame(function () {
        classList.add('default');
      });
    } else {
      classList.remove('default');
      requestAnimationFrame(function () {
        classList.add('active');
      });
    }
  });
});

大きさやアニメーションの速度などいじって自分好みにカスタマイズしてみるといいかもしれません。

33
39
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
39