1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptのイベント処理で、ハンバーガーメニューの開閉アニメーションについて考えてみる【初級編①】

Posted at

はじめに

今回から、JavaScriptのイベント処理→条件分岐の順番で学んでいきます。学ぶ順番の理由は以下の通りです。

①イベント処理から学ぶ理由

  • イベント処理は、ユーザーとのインタラクション(クリック、ホバー、キーボード入力など)を管理するために必要です。
  • 実際の動作が視覚的に確認できるため、学習が直感的に理解しやすく、イベント処理から学ぶことで、ユーザーインターフェースの基本的なインタラクションを扱えるようになります。

②イベント処理で学ぶ内容

  • ハンバーガーメニューの開閉アニメーション、スムーズスクロールを作りたい。

PC版ヘッダーメニューのコード解説

ハンバーガーメニュー01.png

最初はPCで見ると仮定して、ヘッダーのナビゲーションは全て表示するように考えます。

HTML5のコード解説

<!-- ヘッダー -->
<header class="header wrapper">
  <div class="logo"><a href="#">LOGO</a></div>
    <nav class="pc-nav">
       <ul>
          <li><a href="#">MENU</a></li>
          <li><a href="#">MENU</a></li>
          <li><a href="#">MENU</a></li>
       </ul>
    </nav>
    <nav class="sp-nav">
       <ul>
          <li><a href="#">MENU</a></li>
          <li><a href="#">MENU</a></li>
          <li><a href="#">MENU</a></li>
       </ul>
    </nav>
</header>
<!-- /ヘッダー -->
  • pc-navとsp-navの2つに分けて、それぞれサイズに合わせて表示できるように考えました。

CSS3のコード解説

/* ヘッダー */
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 20px;
}

.logo {
  font-size: 35px;
  font-weight: bold;
}

.header ul {
  display: flex;
  gap: 30px;
}

.sp-nav {
  display: none;
}
  • ヘッダーとナビゲーションメニューは、display: flex;で横並びにし、ワイヤーフレーム通りに制作しました。.sp-navはdisplay: none;を設定し、レスポンシブ時のナビゲーションメニューは非表示しました。

レスポンシブ版ヘッダーメニューのコード解説

ハンバーガーメニュー02.png

次にレスポンシブに対応した場合を考えていきます。ナビゲーションメニューは、三本線にまとめ、非表示の準備をします。

HTML5のコード解説

<!-- ヘッダー -->
<header class="header wrapper">
  <div class="logo"><a href="#">LOGO</a></div>
    <nav class="pc-nav">
       <ul>
          <li><a href="#">MENU</a></li>
          <li><a href="#">MENU</a></li>
          <li><a href="#">MENU</a></li>
       </ul>
    </nav>
    <nav class="sp-nav">
       <ul>
          <li><a href="#">MENU</a></li>
          <li><a href="#">MENU</a></li>
          <li><a href="#">MENU</a></li>
       </ul>
    </nav>
    <!-- ハンバーガーメニュー -->
      <div id="hamburger">
        <span></span>
      </div>
    <!-- /ハンバーガーメニュー -->
</header>
<!-- /ヘッダー -->
  • .sp-navの下に#hamburgerを設置し、spanタグで三本線を表現しています。

CSS3のコード解説

/* ハンバーガーメニュー */
@media screen and (max-width: 640px) {
  .header ul {
    display: none;
  }
  .sp-nav {
    z-index: 1;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100vh;
    display: block;
    width: 100%;
    background: rgba(255, 68, 0, 0.8);
    opacity: 0;
    transform: translateY(-100%);
    transition: opacity 0.3s ease-in-out, left 0.3s ease-in-out;
  }
  #hamburger {
    position: relative;
    display: block;
    width: 30px;
    height: 25px;
    margin: 0 0 0 auto;
    cursor: pointer;
    z-index: 999;
  }
  #hamburger span,
  #hamburger::before,
  #hamburger::after {
    position: absolute;
    left: 0;
    display: block;
    width: 100%;
    height: 2px;
    background-color: #333;
    transition: all 0.3s ease-in-out; /* 線のアニメーション */
  }
  #hamburger span {
    position: absolute;
    top: 50%;
    left: 0;
    display: block;
    width: 100%;
    height: 2px;
    background-color: #333;
    transform: translateY(-50%);
  }
  #hamburger::before {
    content: "";
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 2px;
    background-color: #333;
  }
  #hamburger::after {
    content: "";
    display: block;
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 2px;
    background-color: #333;
  }
  • .hamburger-active: このクラスが追加されたとき、ハンバーガーメニューの線が45度回転し、クロスするアニメーションを実現します。JavaScriptでこのクラスをトグルすることで、メニューの開閉時にハンバーガーアイコンが変化します。

  • .sp-nav.open: メニューが開いている状態を表現するクラスで、opacity: 1とtransform: translateY(0)により、ナビゲーションメニューが表示されます。

開閉ハンバーガーメニューのコード解説

ハンバーガーメニュー03.png

最後に、ハンバーガーメニューをクリック時の動きとその他アニメーションを考えます。

CSS3のコード解説

/* メニューが開いたときのクロススタイル */
  .hamburger-active #hamburger span {
    transform: rotate(45deg); /* 中央の線を45度回転 */
  }
  .hamburger-active #hamburger::before {
    top: 50%;
    transform: rotate(45deg); /* 上の線を45度回転させてクロス */
  }
  .hamburger-active #hamburger::after {
    bottom: 50%;
    transform: rotate(-45deg); /* 下の線を-45度回転させてクロス */
  }
  .sp-nav.open {
    opacity: 1;
    transform: translateY(0);
    visibility: visible;
    transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out, visibility 0s; /* visibilityは即表示 */
  }
  .sp-nav ul {
    padding: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    height: 100%;
  }
  .sp-nav li {
    margin: 0;
    padding: 0;
  }
  .sp-nav li span {
    font-size: 15px;
    color: #333;
  }
  .sp-nav li a,
  .sp-nav li span {
    display: block;
    padding: 20px 0;
  }
}
  • ハンバーガーメニューは、レスポンシブ時に表示するよう設定します。そのため、.pc-menuは非表示にし、transform: rotate();で上下にそれぞれ45度と-45度回転してクロスするように見せています。

  • メニューが閉じているときは、opacity: 0 と transform: translateY(-100%) によって画面上部に隠れています。

  • メニューが開くと、opacity: 1 と transform: translateY(0) によってメニューがフェードインしながらスライドして表示されます。

  • レスポンシブ時、ハンバーガーメニューがクリックされると、ナビゲーションメニュー(.sp-nav)が表示され、display: flex で縦方向にリストが並びます。

JavaScriptのコード解説

document.getElementById("hamburger").addEventListener("click", function () {
  // ハンバーガーメニューのクラスをトグル
  document.querySelector(".sp-nav").classList.toggle("open");
  // ハンバーガーのクロス用クラスをトグル
  document.body.classList.toggle("hamburger-active");
});
  • document.querySelector(".sp-nav").classList.toggle("open");では、ここでは、sp-nav要素に openクラスを追加または削除しています。このクラスが追加されると、CSSで設定されたopacityや transformのアニメーションによってメニューが開閉します。

  • document.body.classList.toggle("hamburger-active");では、body要素にhamburger-activeクラスを追加または削除しています。このクラスは、CSSで設定した #hamburger spanや#hamburger::before、#hamburger::afterのアニメーションを制御し、ハンバーガーアイコンが3本線からクロス状に変化します。

  • .sp-navにopen クラスがトグルされ、メニューがスライドイン/スライドアウトするアニメーションが実行されます。bodyにhamburger-activeクラスがトグルされ、ハンバーガーメニューのアイコンがクロス形に変わります。

全体のコード一覧

See the Pen JavaScriptのイベント処理で、ハンバーガーメニューの開閉アニメーションについて考えてみる by Uka Suzuki (@uukasuzuki_) on CodePen.

疑問

今回の記事を通して、3点疑問があります。今後の知見を深めるため、解決策やアドバイス、ご意見など頂けると幸いですm(_ _)m

  1. ハンバーガーメニューの三本線をクロスさせるする時、微妙にずれている気がします。綺麗にクロスするにはどうすればいいでしょうか?角度や横幅など考えましたが、悩んでいます。
  2. ハンバーガーメニューをクリックした時、背景色をゆっくり右からフェードインで表示させ、また閉じる時にも同様にゆっくりフェードアウトさせたいです。
  3. スムーズに情報伝達を発信するために、UIパーツを作る時にコーディングで気を付ける点はありますか?

まとめ

一からハンバーガーメニューをレスポンシブ対応用に制作しました。クリック時の操作性とスムーズさを考えるのが、一番難しかったです。

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?