1. ASHIRIのふろんとあれ、なんだっけぇ
  2. なんだっけぇ一覧
  3. HTML/CSS
  4. 【ドロワーメニュー】スライドインするメニューパネルを実装しよう

【ドロワーメニュー】スライドインするメニューパネルを実装しよう

CATEGORY : HTML/CSS
【ドロワーメニュー】スライドインするメニューパネルを実装しよう 【ドロワーメニュー】スライドインするメニューパネルを実装しよう
先日アプリにJSでドロワーメニューをいれた経緯もあり、今回はドロワーメニューについてCSSを使用したjsライブラリのスクリプトVerとjavaScriptのスクリプトVerの2パターンの書き方を紹介させていただきます。結構今更感はありますが、わりと紹介されているサイトが長文のスクリプトが多いのと、JSライブラリをjavaScriptとして紹介されている方も中にはいらっしゃるようです。そこで、ライブラリと生のJSの違いと上から意見のようでたいへん恐縮ではありますが、スクリプト短縮できない? cssアニメーション発動で十分では?と思い、ご紹介をさせていただきます。
目次

    ドロワーメニューとは

    ドロワーメニューとは、スマートフォンサイトでボタンをクリックすると左からもしくは右からスライドして現れるナビゲーションを格納しているメニューの事です。近年はおしゃれ感もありPCサイトでも復旧しています。イラストは右から左にスライドインしてくる例です。

     

    ドロワーメニューの基本的仕組み

    以前ならJavaScriptで試行錯誤とやり方に苦労ありますが、これくらいはCSSで仕組みとアニメーションを考えるのみでとても簡単です。それでは基本的仕組みをご説明させていただきます。まずドロワーメニューを表示領域外に設置しましょう。

     

    position:fixedを利用してドロワーメニュー分の横幅を表示領域外にマイナス設置します。参考でいうところは右から左にスライドインしますので、right:-横幅サイズ分となります。

     

    ハンバーガーボタンがクリックされたらCSSを追加というアニメーションのエンジンはJSで書きますので、先にアニメーションの仕組みをCSSで構造しましょう。ボタンがクリックされると領域に出したいとする場合、rightが0となれば、右端を基準に表示領域に戻ります。そのためにアニメーション発動のキーを用意します。よく私はトリガーと呼びます。母体にトリガーがあればアニメーション発動し、なければアニメーションせずもとの姿のまま、今回はbodyタグにトリガーがあればとして進めます。

     

    どうでしょうか。トリガーとCSSアニメーションを使えば、いろいろなアニメーションが対応できます。発動するCSSを構造し、JSでクリックしたときやホバーをしたときのトリガーとなるスクリプトを書くだけです。単純な仕組みですね。

     

     

    実装について

    それでは実装について確認してみましょう。まずはマークアップを下記例とします。

    マークアップで骨組み

    
      <div id="wrap">
        <section>
          <button type="button" id="hamburger">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <nav class="menu">
            <ul>
            <li><a href="">NAVI01</a></li>
            <li><a href="">NAVI02</a></li>
            <li><a href="">NAVI03</a></li>
            <li><a href="">NAVI04</a></li>
            </ul>
          </nav>
        </section>
        <main id="contents">
          <section>
            コンテンツ
          </section>
        </main>
      </div><!-- wrap -->
    

     

    ハンバーガーボタンとドロワーメニューを用意して、mainタグがあるだけのシンプルなマークアップです。

     

    見た目とアニメーションをCSSで定義

    
    #contents{
      width: 100%;
      height: 100vh;
      background: #F6F1D2;
      display: flex;
      justify-content: center;
      align-items: center;
      transform: translateX(0);
      transition: all 400ms cubic-bezier(1.000, 0.000, 0.000, 1.000);
    }
    #hamburger {
      cursor: pointer;
      display: block;
      position: fixed;
      z-index: 2;
      top: 1rem;
      right: 1rem;
      background: transparent;
      width: 3rem;
      height: 2.8rem;
      border: none;
    & .icon-bar{
        position: absolute;
        left: 0;
        width: 100%;
        height: 4px;
        border-radius: 4px;
        background: #000;
        transition: all 400ms cubic-bezier(1.000, 0.000, 0.000, 1.000);
      &:nth-child(1) {
          top: 0;
        }
      &:nth-child(2) {
          top: 20px;
      }
      &:nth-child(3) {
          bottom: 0;
      }
    }
    &.active{
      & .icon-bar{
          background: #000;
          &:nth-child(1) {
              background: #fff;
              transform: translateY(20px) rotate(-45deg);
          }
          &:nth-child(2) {
              opacity: 0;
          }
          &:nth-child(3) {
              background: #fff;
              transform: translateY(-20px) rotate(45deg);
            }
        }
    }
    }
    .menu {
      position: fixed;
      top: 0;
      right: -100%;
      z-index: 1;
      width: 100%;
      height: 100%;
      padding-top: 10rem;
      background: #008880;
      transition: all 400ms cubic-bezier(1.000, 0.000, 0.000, 1.000);
      & ul{
          & li a{
              font-size: 2.5rem;
              line-height: 3rem;
              letter-spacing: .85rem;
              color:#fff;
              text-decoration: none;
              text-align: center;
              margin-bottom: 4rem;
          }
      }
    }
    .drawer-opened{
      & .menu{
          right: 0;
      }
      & #contents{
          transform: translateX(-150px);
      }
    }
    

     

    仕組みは基本と同じです。ハンバーガーボタンにはクリックされたら、activeというクラスが追加され、バッテンになるアニメーションの仕組みを書いています。またhoverやクリックなどの動作、変化前と変化後を滑らかにつなげるお手軽プロパティtransitionにてアニメーションを設定しています。簡単にアニメーションが滑らかに設定できる素晴らしいプロパティです。
    ※mainタグにも左150pxズレるだけで全体に動きが出て、おしゃれになります。

     

    JSライブラリjQueryにて発動

    それではアニメーションを動かすトリガーはどのようなものか、下記がトリガーのエンジンとなります。

    
    $(function(){
      var body = $('body');
      var hamburger = $('#hamburger');
      hamburger.on('click', function() {
          if(body.hasClass('drawer-opened')){
            body.removeClass('drawer-opened');
            $(this).removeClass('active');
          } else {
            body.addClass('drawer-opened');
            $(this).addClass('active');
          };
      });
    });
    

     

    読んで字のごとくですね。上から下に処理が流れ真偽していきます。
    ・ハンバーガーボタンをクリックしたら
    ・bodyタグにdrawer-openedクラスがあるかないか確認
    ・あれば、bodyタグからdrawer-openedクラスを削除
    ・あれば、ハンバーガーボタンからactiveクラスを削除
    ・なければ、bodyタグにdrawer-openedクラスを追加
    ・なければ、ハンバーガーボタンにactiveクラスを追加
    これで処理の出来上がりです。簡単でしかもJSライブラリだと行数もたった数行です。

     

    JavaScriptにて発動

    ではjavaScriptでスクリプトを書くとどうなるのか確認してみましょう。

    
      (function () {
        const $body = document.querySelector('body');
        const $hamburger = document.getElementById('hamburger');
    
        $hamburger.addEventListener('click', function(){
          $hamburger.classList.toggle('active')
        });
    
        $hamburger.addEventListener('click', navToggle);
    
        function navToggle() {
          if ($body.classList.contains('drawer-opened')) {
            closeFunc();
          } else {
            openFunc();
          }
        }
        function openFunc() {
          $body.classList.add('drawer-opened');
        }
        function closeFunc() {
          $body.classList.remove('drawer-opened');
        }
      })();
    

     

    この程度のギミックなのでさほど差がでるわけではありませんが、JSライブラリと見比べると行数は増えていますね。
    クラスがあるかないかはJSライブラリであればhasClassでしたが、JavaScriptではcontainsで有無のチェックをしています。この程度の行数でopenFuncやcloseFunc独自関数にまとめるほどではないですが、行数が増えた場合の見やすさと関数を分ける事でどのギミック用かわかるよう管理できますね。

     

    まとめ

    いかがでしたでしょうか。今回はドロワーについてご紹介させていただきました。世の中で公開されているWEBサイトのアニメーションは、CSSにて構造し発動がJSというのが主流ではないかなと思います。またなんといっても、Vueなどフレームワークそれぞれにアニメーションのスクリプトはありますが、JavaScriptとCSSを使う事で効率よくアニメーションができ、追加などの管理がしやすいのではないかと私は思います。

    以上となります。できる限りわかりやすく伝えようとしても書くのは難しいです。
    コードや記事の書き方について気になるところがあれば、アドバイスいただけると嬉しいです。

    【ドロワーメニュー】スライドインするメニューパネルを実装しよう
    CATEGORY : HTML/CSS

    アシリソリューション

    アシリソリューション

    アシリ・ソリューション

    要件定義からブラッシュアップ/実装運用まで一貫して担当。また内部対策を中心に、GTM・GA4・Looker Studioと分析・改善案の策定も進めています。北緯43度マルチエンジニア

    最近のなんだっけぇ

    1. 【javascript基礎】自動見積フォームの仕組みを理解する

      【javascript基礎】自動見積フォームの仕組みを理解する

    2. 【Node基礎】APIエンドポイントの保護を理解する

      【Node基礎】APIエンドポイントの保護を理解する

    3. 【Node基礎】RESTful API を理解する

      【Node基礎】RESTful API を理解する

    4. 【Vue基礎】Vue Routerのネストを理解する

      【Vue基礎】Vue Routerのネストを理解する

    5. 【Vue基礎】v-onディレクティブを理解する

      【Vue基礎】v-onディレクティブを理解する

    6. 【Vue基礎】v-modelディレクティブを理解する

      【Vue基礎】v-modelディレクティブを理解する

    1. API
    2. computed
    3. css
    4. ECMA
    5. javascript
    6. jquery
    7. Node
    8. php
    9. reactive
    10. reduce メソッド
    11. ref
    12. sass
    13. SSH
    14. v-bind
    15. v-on
    16. Vue
    17. Vディレクティブ
    18. wordpress
    19. セキュリティ対策
    20. 入れ子
    21. 繰り返し処理
    22. 関数