見出し画像

CLOSEボタンと領域外クリックで閉じるハンバーガーメニューの作り方

よく見かけるハンバーガーメニューは、アイコンをクリックすると形が×などに変形すると思います。今回は、下記の条件でハンバーガーメニューを作成して作り方を自分用にまとめてみました。
①アイコンは変形しない。
②ナビゲーション内の別ボタン(CLOSEボタン)をクリックすると閉じる。
③領域外をクリックすると閉じる。

-完成DEMO-

HTML

<header id="header">
  <section>
    <div class="header-sp">
      <h1 class="site-logo"> <a href="#"><img src="https://dl.easyuploader.cloud/20220130202634_77717844.svg" alt="#"></a> </h1>
      <!-- hamburger-menu -->
      <div id="navArea">
        <nav>
          <div class="inner">
            <ul>
              <li><a href="#">TEST1</a></li>
              <li><a href="#">TEST2</a></li>
              <li><a href="#">TEST3</a></li>
              <li><a href="#">TEST4</a></li>
              <li><a href="#">TEST5</a></li>
            </ul>
            <div class="nav-sns-erea">
              <p class="txt-title">Social</p>
              <ul class="sns-contents">
                <li>
                  <p>Instagram</p>
                </li>
                <li>
                  <p>YouTube</p>
                </li>
              </ul>
            </div>
            <div class="nav-other-erea">
              <p class="txt-title">Site By</p>
              <ul class="other-contents">
                <a href="#">
                  <li>Delusion Design.</li>
                </a>
              </ul>
            </div>
            <!-- toggle_btn -->
            <div class="close_btn"> <span class="close">CLOSE</span> </div>
          </div>
        </nav>
        <div class="toggle_btn"> <span class="open"></span> <span class="open"></span> <span class="open"></span> </div>
        <!-- mask -->
        <div id="mask"></div>
      </div>
    </div>
  </section>
  <main>
    <div class="main-wrapper">
      <p>content</p>
    </div>
  </main>
  <footer id="footer">
    <p>footer</p>
  </footer>

CSS

/*---------------------------
        
      0.common setting   

---------------------------*/
* {
  margin: 0;
  padding: 0;
}

html {
  font-size: 100%;
}

body {
  font-family: 'Noto Sans JP', sans-serif;
  font-size: 1rem;
  color: #333333;
  line-height: 1.5;
}

ul {
  list-style: none;
}
/*---------------------------
        
         1. header   

---------------------------*/
.header-sp {
  position: fixed;
  display: flex;
  justify-content: center;
  align-items: center;
  /*paddingとborderを幅と高さに含める*/
  box-sizing: border-box;
  background-color: #262421;
  width: 100%;
  height: 60px;
  z-index: 9998;
  border-bottom: 1px solid #262421;
  /*下線の色が変わる時間を調整*/
  transition: all 1s ease;
}

/*line-heightにh1タグの高さよりも小さい値「0」を指定することで、h1タグの上下の余白が消えるため、ロゴ画像の高さと揃う*/
.site-logo {
  display: inline-block;
  line-height: 0;
}

/* aタグのリンク範囲を親要素のサイズに広げる */
.site-logo a {
  display: block;
}

.site-logo img {
  width: 200px;
}

/*           nav
---------------------------*/
nav {
  display: block;
  position: fixed;
  top: 0;
  /* ナビゲーションを表示させる位置を指定する */
  right: -1800px;
  bottom: 0;
  /* メニューアイコンを押下した際のナビゲーションメニューの横幅を指定する */
  width: 90%;
  background: #262421;
  overflow-x: hidden;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /*  ナビゲーションを表示する速度を指定する  */
  transition: all 0.8s;
  z-index: 4;
  opacity: 0;
}

.open nav {
  /* ナビゲーションの表示位置を指定する */
  right: 0;
  /* ナビゲーションの透過率を指定する */
  opacity: 1;
}

nav .inner {
  padding: 4.0625rem 1.5625rem 1rem 1.5625rem;
}

nav .inner ul {
  display: inlineblock;
  list-style: none;
  line-height: 1;
  margin: 0;
}

nav .inner ul li {
  position: relative;
  margin: 15px 0;
}

nav .inner ul li a {
  display: inlineblock;
  color: #fff;
  font-size: 1.5rem;
  transition-duration: 0.2s;
  text-decoration:none;
}

nav .nav-sns-erea,nav .nav-other-erea {
  margin-top: 30px;
}

nav .nav-sns-erea li,nav .nav-other-erea li {
  color: #fff;
  font-size: 0.9375rem;
}
.other-contents a {
  text-decoration:none;
}

nav .txt-title {
  color: #919090;
  font-size: 0.75rem;
  font-family: 'Libre Baskerville', serif;
  font-style: italic;
  font-weight: 400;
  line-height: 1;
}

nav .sns-contents,nav .other-contents {
  margin-top: 10px;
}

nav .sns-contents p {
  display: inline-block;
}

nav .other-contents p {
  display: inline-block;
  font-size: 1rem;
  font-weight: 400;
}

/*       toggle_btn
---------------------------*/
.toggle_btn {
  display: block;
  position: fixed;
  top: 15px;
  right: 15px;
  width: 30px;
  height: 30px;
  cursor: pointer;
  z-index: 3;
}
.toggle_btn .open {
  display: block;
  position: absolute;
  left: 0;
  width: 30px;
  height: 1px;
  background-color: #fff;
  border-radius: 4px;
}
.toggle_btn .open:nth-child(1) {
  top: 15px;
}
.toggle_btn .open:nth-child(2) {
  top: 20px;
}
.toggle_btn .open:nth-child(3) {
  top: 25px;
}

/*1つ目の要素のafter要素にMenu表示を指定する*/
.toggle_btn .open:nth-child(1)::after {
  content:"Menu";
  position: absolute;
  top: -15px;
  left: 0;
  color: #fff;
  font-size: 0.625rem;
  line-height: 1;
  text-transform: uppercase;
}

/* クリック時にハンバーガーメニューを非表示にする */
.open .toggle_btn .open {
  display: none;
}

/*       close_btn
---------------------------*/
/* 非表示にしたハンバーガーメニューの変わりに表示するアイコンを指定する */
.close_btn .close::before {
  position: absolute;
  top: 0px;
  left: -20px;
  font-family: 'Font Awesome 5 Free';
  content: "\f057";
  font-size: 1rem;
  font-weight: 600;
}

.close_btn {
  position: absolute;
  color: #fff;
  cursor: pointer;
  /* 非表示にしたハンバーガーメニューの変わりにCLOSEを表示する位置を指定する   */
  top: calc(0% + 25px);
  left: calc(100% - 80px);
  z-index: 4;
}

/*          mask
---------------------------*/

#mask {
  display: none;
  transition: all .5s;
}

/* ナビゲーションが展開された部分の外側余白を指定する */
.open #mask {
  display: block;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #000;
  opacity: .8;
  z-index: 2;
  cursor: pointer;
}
/*---------------------------
        
          2. main   

---------------------------*/
.main-wrapper {
  height: 600px;
  background-color: #F8F7F5;
  display: flex;
  justify-content: center;
  align-items: center;
}

.main-wrapper p {
  font-size: 5rem;
}

/*---------------------------
        
          3. footer   

---------------------------*/

#footer {
  height: 600px;
  background-color: #333333;
  display: flex;
  justify-content: center;
  align-items: center; 
}

#footer p {
  font-size: 5rem;
  color: #fff;
}

JS

   // spナビ
    (function($) {
      var $nav   = $('#navArea');
      var $btn   = $('.toggle_btn');
      var $mask  = $('#mask');
      var $close_btn   = $('.close_btn');
      var open   = 'open'; // class
      // menu open close
      $btn.on( 'click', function() {
        $nav.addClass( open );
      });
      $close_btn.on( 'click' , function() {
        $nav.removeClass( open );
      });
      // mask close
      $mask.on('click', function() {
        $nav.removeClass( open );
      });
    } )(jQuery);

    const setFillHeight = () => {
      const vh = window.innerHeight * 0.01;
      document.documentElement.style.setProperty('--vh', `${vh}px`);
    }

    // ここからリサイズの対応
    let vw = window.innerWidth;
    window.addEventListener('resize', () => {
      if (vw === window.innerWidth) {
      // 画面の横幅にサイズ変動がないので処理を終える
        return;
      }

      // 画面の横幅のサイズ変動があった時のみ高さを再計算する
      vw = window.innerWidth;
      setFillHeight();
    });

    // 実行
    setFillHeight();

この記事が気に入ったらサポートをしてみませんか?