【コピペで実装】初心者必見!ハンバーガーメニューの作り方

モダンなウェブデザインに欠かせないハンバーガーメニューは、スマートフォンやタブレットの普及により、今やほとんどのウェブサイトで見かける定番の要素となっています。

この記事では、ハンバーガーメニューの基本から実践的な実装方法まで、初心者にもわかりやすく解説します。

詳しく解説していますので、コードだけほしい方はこちらから

目次

見本

今回は下記のようなハンバーガーメニューを作っていきます。

See the Pen ハンバーガーメニュー by ryoma (@hwjgdjpk-the-decoder) on CodePen.

ポイントは下記になります。

  • 3本線をクリックすると✕印になり、色は白くなる
  • 3本線をクリックするとドロワーメニューが出てくる
  • ドロワーメニューのリンクをクリックすると閉じる
  • ドロワーメニューのメニュー以外をクリックしても閉じる
  • ドロワーメニューのリンクがページ内リンクでも閉じる

ハンバーガーメニューの見た目の制作

HTML

<!-- ハンバーガーメニュー -->
<div class="hamburger js-hamburger sp-show">
  <span></span>
  <span></span>
  <span></span>
</div>
<!-- ドロワーメニュー -->
<div class="drawer js-drawer">
  <div class="drawer-inner">
    <div class="drawer__nav">
      <ul class="drawer__list">
        <li class="drawer__item">
          <a href="#" class="drawer__link">Home</a>
        </li>
        <li class="drawer__item">
          <a href="#about" class="drawer__link">About</a>
        </li>
        <li class="drawer__item">
          <a href="#works" class="drawer__link">Works</a>
        </li>
        <li class="drawer__item">
          <a href="#service" class="drawer__link">Service</a>
        </li>
      </ul>
    </div>
  </div>
</div>

まずはHTMLですが、

大きく分けて以下の2つの構造になっています。

  • ハンバーガー(3本線の部分)
  • ドロワーメニュー(クリックすると出てくるメニュー)

ハンバーガーメニューの部分

<div class="hamburger js-hamburger sp-show">
  <span></span>
  <span></span>
  <span></span>
</div>
  • hamburger: このクラスは、ハンバーガーメニューアイコン(3本の横線)のスタイリングに使用されます。
  • js-hamburger: JavaScriptでイベントリスナー(クリックイベントなど)を追加する際に使用するクラスです。これにより、メニューの開閉を制御できます。
  • sp-show: これは「スマートフォン表示時のみ表示(show)」を意味するクラスです。レスポンシブデザインにおいて、特定の画面サイズでのみこの要素を表示するために使用されます。
  • <span></span>: これら3つの<span>タグは、ハンバーガーメニューの各線を表しています。CSSを使用してこれらにスタイリングを適用することで、ユーザーに視覚的に認識されるアイコンが形成されます。

ドロワーメニューの部分

<div class="drawer js-drawer">
  <div class="drawer-inner">
    <div class="drawer__nav">
      <ul class="drawer__list">
        <li class="drawer__item">
          <a href="#" class="drawer__link">Home</a>
        </li>
        <li class="drawer__item">
          <a href="#about" class="drawer__link">About</a>
        </li>
        <li class="drawer__item">
          <a href="#works" class="drawer__link">Works</a>
        </li>
        <li class="drawer__item">
          <a href="#service" class="drawer__link">Service</a>
        </li>
      </ul>
    </div>
  </div>
</div
  • drawer: このクラスは、ドロワーメニュー(ハンバーガーメニューをクリックすると出現するナビゲーションメニュー)のスタイリングに使用されます。
  • js-drawer: こちらもJavaScriptの操作対象となるクラスです。メニューの開閉などの動作を制御するために使用されるためのクラスです。
  • drawer-inner は外側のコンテナを、drawer__nav はナビゲーション部分をそれぞれ表しています。
  • <ul class="drawer__list">: メニュー項目のリストを表します。この中に、ナビゲーションリンクを含むリストアイテムが配置されます。
  • <li class="drawer__item"><a href="#" class="drawer__link">: これらはそれぞれナビゲーションリンクを含むリストアイテムです。

CSS

/*=========================================
#hamburger
=========================================*/
.hamburger {
    position: fixed;
    top: 20px;
    right: 20px;
    z-index: 150;
    width: 30px;
    height: 30px;
    cursor: pointer;
}

.hamburger.is-active span:nth-child(1) {
    top: 50%;
    transform: translate(-50%, -50%) rotate(135deg);
}

.hamburger.is-active span:nth-child(2) {
    opacity: 0;
}

.hamburger.is-active span:nth-child(3) {
    top: 50%;
    transform: translate(-50%, -50%) rotate(-135deg);
}

.hamburger span {
    position: absolute;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 100%;
    height: 2px;
    background-color: #333333;
    transition: transform .3s;
}

.hamburger.is-active span {
    background-color: #ffffff;
}

.hamburger span:nth-child(1) {
    top: 30%;
}

.hamburger span:nth-child(2) {
    top: 60%;
}

.hamburger span:nth-child(3) {
    top: 90%;
}

/*=========================================
#drawer
=========================================*/
.drawer {
    visibility: hidden;
    opacity: 0;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 130;
    width: 100%;
    height: 100vh;
    background-color: #333333;
    transition: opacity .3s, visibility .3s;
}

.drawer.is-active {
    visibility: visible;
    opacity: 1;
}

.drawer-inner {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    padding: 0 20px;
}

.drawer__list {
    display: flex;
    flex-direction: column;

    gap: 50px;
}

.drawer__link {
    color: #ffffff;
}




/* ===============================================
# 共通
=============================================== */
a {
    color: inherit;
    text-decoration: none;
}

img {
    max-width: 100%;
    height: auto;
    background-size: cover;
    background-repeat: no-repeat;
    font-style: italic;
    vertical-align: middle;

    shape-margin: .75rem;
}

/* 実際のプロジェクトではここのコメントを解除して、スマホ時のみ表示させます。 */
/* .sp-show {
  display: none;
}

@media screen and (max-width: 768px) {
  .sp-show {
    display: block;
  }
  .sp-none {
    display: none;
  }
} */

主要なポイントを以下に解説します。

ハンバーガーメニューに関するスタイル

.hamburger {
    position: fixed;
    top: 20px;
    right: 20px;
    z-index: 150;
    width: 30px;
    height: 30px;
    cursor: pointer;
}
  • .hamburgerクラスは、ハンバーガーメニューのアイコンの位置やサイズを定義します。
  • position: fixed; により、アイコンは画面上の固定位置に表示されます。
  • topright で画面の上部と右側からの距離を設定します。
  • z-index は他の要素より前面に表示させるための値です。
  • cursor: pointer; はカーソルがアイコンの上にあるときにポインター(手の形)に変わることを示します。
.hamburger.is-active span:nth-child(1) {
    top: 50%;
    transform: translate(-50%, -50%) rotate(135deg);
}
.hamburger.is-active span:nth-child(2) {
    opacity: 0;
}
.hamburger.is-active span:nth-child(3) {
    top: 50%;
    transform: translate(-50%, -50%) rotate(-135deg);
}
  • .hamburger.is-active は、メニューがアクティブ(開かれた)状態のスタイリングを定義します。
  • 1つ目と3つ目の span は、45度の角度で交差するように回転します(クローズアイコンの形になります)。
  • 2つ目の span は透明になり、見えなくなります。
.hamburger span {
    position: absolute;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 100%;
    height: 2px;
    background-color: #333333;
    transition: transform .3s;
}
  • span 要素には、ハンバーガーメニューの各線のスタイルが定義されています。

ドロワーメニューに関するスタイル

.drawer {
    visibility: hidden;
    opacity: 0;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 130;
    width: 100%;
    height: 100vh;
    background-color: #333333;
    transition: opacity .3s, visibility .3s;
}
.drawer.is-active {
    visibility: visible;
    opacity: 1;
}
  • .drawer は、ドロワーメニューの基本的なスタイルを定義します。
  • visibility: hidden;opacity: 0; で初期状態ではメニューが見えないように設定されています。
  • .is-active が追加されると、メニューが表示されます(visibility: visible;opacity: 1;)。

.drawer-inner {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    padding: 0 20px;
}

.drawer__list {
    display: flex;
    flex-direction: column;

    gap: 50px;
}
.drawer__link {
    color: #ffffff;
}
  • これらのクラスは、ドロワーメニュー内部のレイアウトとスタイルを制御します。

共通

共通以下のCSSは毎回設定するもので、今回はコメントアウト部分がありますが、今回は説明用にPCでも表示できる用にしているので、コメントアウトがあります。

実際に使用するときはPCで表示する必要はないので、下記部分のコメントアウトは外して使ってください。

/* .sp-show {
  display: none;
}

@media screen and (max-width: 768px) {
  .sp-show {
    display: block;
  }
  .sp-none {
    display: none;
  }
} */

以上がCSSになります。

ハンバーガーメニューの動きの制作

見た目が完成してので、次は動きをつけてメニューの開閉ができるようにしていきます。

ポイントをおさらいすると以下のようになります。

  • 3本線をクリックすると✕印になり、色は白くなる
  • 3本線をクリックするとドロワーメニューが出てくる
  • ドロワーメニューのリンクをクリックすると閉じる
  • ドロワーメニューのメニュー以外をクリックしても閉じる
  • ドロワーメニューのリンクがページ内リンクでも閉じる

JavaScriptの完成コード

/*=========================================
#ハンバーガーメニュー
=========================================*/
const hamburger = document.querySelector(".js-hamburger");
const drawer = document.querySelector(".js-drawer");
const drawerLinks = document.querySelectorAll(".js-drawer a");

hamburger.addEventListener('click', () => {
  hamburger.classList.toggle('is-active');
  drawer.classList.toggle('is-active');
});

drawerLinks.forEach(drawerLink => {
  drawerLink.addEventListener('click', () => {
    hamburger.classList.remove('is-active');
    drawer.classList.remove('is-active');
  });
});

drawer.addEventListener('click', () => {
  hamburger.classList.remove('is-active');
  drawer.classList.remove('is-active');
});

上記コードは、ハンバーガーメニューとドロワーメニューの動的な挙動を制御するためのものです。

主要な部分を解説します。

ハンバーガーメニューの動作制御

const hamburger = document.querySelector(".js-hamburger");
const drawer = document.querySelector(".js-drawer");
  • ここでは、ハンバーガーメニューのアイコン(.js-hamburger)とドロワーメニュー(.js-drawer)をそれぞれ変数に格納しています。これにより、後続のコードでこれらの要素を操作できるようになります。
hamburger.addEventListener('click', () => {
  hamburger.classList.toggle('is-active');
  drawer.classList.toggle('is-active');
});
  • ハンバーガーメニューのアイコンにクリックイベントリスナーを追加しています。
  • ユーザーがアイコンをクリックすると、.is-activeクラスが追加されたり削除されたりします。このクラスの追加/削除により、CSSで定義されたスタイルが適用され、メニューの開閉が実現されます。

ドロワーメニューのリンクに対する動作

const drawerLinks = document.querySelectorAll(".js-drawer a");

drawerLinks.forEach(drawerLink => {
  drawerLink.addEventListener('click', () => {
    hamburger.classList.remove('is-active');
    drawer.classList.remove('is-active');
  });
});
  • ドロワーメニュー内の各リンクに対して、クリックイベントリスナーを追加しています。
  • ユーザーがどれかのリンクをクリックすると、ハンバーガーメニューとドロワーメニューの両方から.is-activeクラスが削除され、メニューが閉じます。

ドロワーメニュー自体に対する動作

drawer.addEventListener('click', () => {
  hamburger.classList.remove('is-active');
  drawer.classList.remove('is-active');
});
  • ドロワーメニュー全体にもクリックイベントリスナーを追加しています。
  • ユーザーがドロワーメニューの外側(つまりメニュー自体)をクリックすると、同様に.is-activeクラスが削除され、メニューが閉じます。

このJavaScriptコードは、ハンバーガーメニューの開閉や、ドロワーメニュー内のリンクをクリックした際の動作をスムーズに制御するためのものです。ユーザーの操作に対して直感的で応答性の高いインタラクションを提供することが目的です。

完成コード

以下は完成後のコードです。

HTML

<!-- ハンバーガーメニュー -->
<div class="hamburger js-hamburger sp-show">
  <span></span>
  <span></span>
  <span></span>
</div>
<!-- ドロワーメニュー -->
<div class="drawer js-drawer">
  <div class="drawer-inner">
    <div class="drawer__nav">
      <ul class="drawer__list">
        <li class="drawer__item">
          <a href="#" class="drawer__link">Home</a>
        </li>
        <li class="drawer__item">
          <a href="#about" class="drawer__link">About</a>
        </li>
        <li class="drawer__item">
          <a href="#works" class="drawer__link">Works</a>
        </li>
        <li class="drawer__item">
          <a href="#service" class="drawer__link">Service</a>
        </li>
      </ul>
    </div>
  </div>
</div>

CSS


/*=========================================
#hamburger
=========================================*/
.hamburger {
    position: fixed;
    top: 20px;
    right: 20px;
    z-index: 150;
    width: 30px;
    height: 30px;
    cursor: pointer;
}

.hamburger.is-active span:nth-child(1) {
    top: 50%;
    transform: translate(-50%, -50%) rotate(135deg);
}

.hamburger.is-active span:nth-child(2) {
    opacity: 0;
}

.hamburger.is-active span:nth-child(3) {
    top: 50%;
    transform: translate(-50%, -50%) rotate(-135deg);
}

.hamburger span {
    position: absolute;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 100%;
    height: 2px;
    background-color: #333333;
    transition: transform .3s;
}

.hamburger.is-active span {
    background-color: #ffffff;
}

.hamburger span:nth-child(1) {
    top: 30%;
}

.hamburger span:nth-child(2) {
    top: 60%;
}

.hamburger span:nth-child(3) {
    top: 90%;
}

/*=========================================
#drawer
=========================================*/
.drawer {
    visibility: hidden;
    opacity: 0;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 130;
    width: 100%;
    height: 100vh;
    background-color: #333333;
    transition: opacity .3s, visibility .3s;
}

.drawer.is-active {
    visibility: visible;
    opacity: 1;
}

.drawer-inner {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    padding: 0 20px;
}

.drawer__list {
    display: flex;
    flex-direction: column;

    gap: 50px;
}

.drawer__link {
    color: #ffffff;
}




/* ===============================================
# 共通
=============================================== */
a {
    color: inherit;
    text-decoration: none;
}

img {
    max-width: 100%;
    height: auto;
    background-size: cover;
    background-repeat: no-repeat;
    font-style: italic;
    vertical-align: middle;

    shape-margin: .75rem;
}

.sp-show {
    display: none;
}

@media screen and (max-width: 768px) {
    .sp-show {
        display: block;
    }

    .sp-none {
        display: none;
    }
}

JavaScript

/*=========================================
#ハンバーガーメニュー
=========================================*/
const hamburger = document.querySelector(".js-hamburger");
const drawer = document.querySelector(".js-drawer");
const drawerLinks = document.querySelectorAll(".js-drawer a");

hamburger.addEventListener('click', () => {
  hamburger.classList.toggle('is-active');
  drawer.classList.toggle('is-active');
});

drawerLinks.forEach(drawerLink => {
  drawerLink.addEventListener('click', () => {
    hamburger.classList.remove('is-active');
    drawer.classList.remove('is-active');
  });
});

drawer.addEventListener('click', () => {
  hamburger.classList.remove('is-active');
  drawer.classList.remove('is-active');
});

まとめ

今回は簡単にハンバーガーメニューを作る方法を詳しく解説しました。

ハンバーガーメニューは使う機会も非常に多いので是非この記事をブックマークして、すぐに見返すことができるようにしておくと便利です。

また、このブログでは他にもコーディングに関する記事を投稿していますので、あわせて参考にしてみてください。

あわせて読みたい
5分でわかる!スニペット登録の方法 コーディングの速度を上げたい コードの再利用やタイピングの手間を減らしたい と思っている人は多いのではないでしょうか? そんな人にとって、スニペットは強い味方に...
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次