ハンバーガーメニューが×に変形して背景でも閉じるように実装

背景でも閉じる横からのハンバーガーメニュー

今回は、ハンバーガーメニューをクリックすると表示・非表示が切り替えられ、背景をクリックでもメニューが閉じる仕様にしていきたいと思います。

デモ・サンプル

まずは、下記のデモで、完成形を確認してみましょう。

HTML

<div class="menu">
  <div class="line-list" id="js-hamburger">
    <span></span>
    <span></span>
    <span></span>
  </div>
  <div class="menu-bg" id="js-menu-bg"></div>
  <nav class="global-nav">
    <ul class="link-list">
      <li><a href="#">メニュー1</a></li>
      <li><a href="#">メニュー2</a></li>
      <li><a href="#">メニュー3</a></li>
    </ul>
  </nav>
</div>

htmlの各要素の説明をしていきます。

<div class="line-list" id="js-hamburger">
  <span></span>
  <span></span>
  <span></span>
</div>

ハンバーガーメニューの元になる要素で、spanの3つがハンバーガーメニューの線になる。

<div class="menu-bg" id="js-menu-bg"></div>

メニューが開いた時に、半透明の黒い背景として出現する要素。

後で、タップもしくはクリックで閉じるようにする。

<nav class="global-nav">
  <ul class="link-list">
    <li><a href="#">メニュー1</a></li>
    <li><a href="#">メニュー2</a></li>
    <li><a href="#">メニュー3</a></li>
  </ul>
</nav>

メニューが開いた時の中身となる要素。

好きな数だけメニューは入れれます。

ちなみに、メニューが増えると縦にスクロールできるようにします。

CSS

cssは少し多めになってしまいますが、これでも最低限の大事なソースになります。

/* メニュー固定 */
.menu {
  position: fixed;
  top: 0;
  right: 0;
  width: 100%;
  height: 40px;
}

.line-list {
  display: block;
  transition: all 0.4s;
  box-sizing: border-box;
  position: relative;
  width: 40px;
  height: 40px;
  margin-right: 0;
  margin-left: auto;
  z-index: 300;
}

/* ハンバーガーメニューの棒 */
.line-list span {
  display: block;
  transition: all 0.4s;
  box-sizing: border-box;
  position: absolute;
  top: 50%;
  transform: translateY(50%);
  left: 50%;
  transform: translateX(-50%);
  width: 20px;
  height: 1px;
  background: #333;
}
.line-list span:nth-child(1) {
  margin-top: -6px;
}
.line-list span:nth-child(3) {
  margin-top: 6px;
}

/* ハンバーガーメニューが開くときに×にする */
.line-list.active span:nth-child(1) {
  -webkit-transform: translateY(6px) rotate(-45deg);
  transform: translateY(6px) rotate(-45deg);
  left: 10px;
}
.line-list.active span:nth-child(2) {
  opacity: 0;
}
.line-list.active span:nth-child(3) {
  -webkit-transform: translateY(-6px) rotate(45deg);
  transform: translateY(-6px) rotate(45deg);
  left: 10px;
}

/* メニューが開いたときの黒い半透明の背景 */
.menu-bg {
  position: fixed;
  left: 0;
  top: 0;
  width: 100vw;
  height: 100vh;
  z-index: 100;
  background: #333;
  opacity: 0;
  visibility: hidden;
  transition: all 0.6s;
  cursor: pointer;
}

/* メニューの中身 */
.global-nav {
  position: fixed;
  right: -320px;
  top: 0;
  width: 300px;
  height: 100vh;
  padding-top: 40px;
  background: #fff;
  transition: all 0.6s;
  z-index: 200;
  overflow-y: auto;
}
.link-list {
  display: block;
  margin: 0;
  padding: 0;
}
.link-list li {
  text-align: center;
  padding: 0 14px;
}
.link-list li a {
  display: block;
  padding: 20px 0;
  color: #333;
}
.link-list li:hover {
  background: #464646;
}

/* メニューが横から開く */
.nav-open .global-nav {
  right: 0;
}

/* メニューが横から開いた時の背景 */
.nav-open .menu-bg {
  opacity: 0.8;
  visibility: visible;
}

JavaScript

JavaScriptはそんなに難しくなく、簡単です。

ここはコピペで使い回しても問題ありません。

$(function() {
  function toggleNav() {
    var body = document.body;
    var hamburger = document.getElementById("js-hamburger");
    var blackBg = document.getElementById("js-menu-bg");
    // クリックしたときにクラス付与
    hamburger.addEventListener("click", function() {
      body.classList.toggle("nav-open");
      hamburger.classList.toggle("active");
    });
    // クリックしたときにクラス付与
    blackBg.addEventListener("click", function() {
      body.classList.remove("nav-open");
      hamburger.classList.remove("active");
    });
  }
  toggleNav();
});

処理の流れとしては、背景かハンバーガーメニューのどちらかがクリックされた時に、cssのクラスを付け外しして、メニューが開くようにし、ハンバーガー部分を×に変形させる。

以上になります。

まとめ

ハンバーガーメニューは、何かと使い回しができて、簡単にデザインの変更なども行ないやすいので、しっかりと使えるようになりましょう!

他にもこんな記事があります!