迷い人

日々勉強。勉強の先に何か見つかるといいなぁ

ハンバーガーメニューについて考えてみた

レスポンシブなハンバーガーメニューを作りたくて、色々調べていました。

ただ導入するだけなら、コードのコピペで済むんでしょうが、実装内容をきちんと理解したいと思いこの記事を書いています。

 

以下の記事で紹介さ入れているコードについて、考察しています。

 

www.aiship.jp

 

まずはコード。これを書けばとりあえず動く。

 

html

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <title>Hamburger_Menu</title>
    <link rel="stylesheet" href="css_hamburger2.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script type="text/javascript" src="jquery_hamburger.js"></script>
  </head>
  <body>
    <div id="wrapper">
      <div class="btn-gnavi">
          <span></span>
          <span></span>
          <span></span>
      </div>
      <nav id="global-navi">
        <ul>      
          <li><a href="">トップ</a></li>
          <li><a href="">概要</a></li>
          <li><a href="">特集</a></li>
          <li><a href="">アクセス</a></li>
          <li><a href="">お問い合わせ</a></li>
        </ul>
      </nav>
    </div>
    <div class="main_contents">
      <p>テスト1</p>
      <p>テスト2</p>
      <p>テスト3</p>
      <p>テスト4</p>
      <p>テスト5</p>
      <p>テスト6</p>
      <p>テスト7</p>
      <p>テスト8</p>
      <p>テスト9</p>
      <p>テスト10</p>
      <p>テスト11</p>
      <p>テスト12</p>
      <p>テスト13</p>
      <p>テスト14</p>
      <p>テスト15</p>
      <p>テスト16</p>
      <p>テスト17</p>
    </div>
  </body>
</html>
scss

*, *::before, *::after {
  box-sizing: border-box;
}
#global-navi {
  background:#333;
  position: fixed;
  width: 100%;
}
#wrapper {
  nav {
    ul {
      li{
        display:inline-block;
        font-size: 16px;
        padding:  30px 20px;
        a {
          text-decoration: none;
          color: #ddd;
        }
      }
    }
  }
}
/*スマホ画面でハンバーガーメニューの形にする*/
@media screen and (max-width: 600px) {
  #wrapper {
    nav {
      position: fixed;
      top: 0;
      right: -300px;
      width: 300px;
      height: 100%;
      padding-top: 50px;
      background:#333;
      font-size: 16px;
      ul {
        li {
          display:block;
          padding: 20px 28px;
          a {
            text-decoration: none;
            color: #ddd;
          }
        }
      }
    }
    .btn-gnavi {
      position: fixed;
      top: 20px;
      right: 20px;
      width: 30px;
      height: 24px;
      z-index: 2;
      cursor: pointer;
      -webkit-transition: all 400ms;
      transition: all 400ms;
      span {
        position: absolute;
        width: 30px;
        height: 4px;
        background: #666;
        border-radius: 10px;
        -webkit-transition: all 400ms;
        transition: all 400ms;
        &:nth-child(1) {
          top: 0;
        }
        &:nth-child(2) {
          top: 10px;
        }
        &:nth-child(3) {
          top: 20px;
        }
      }
    }
    .btn-gnavi.open {
      -webkit-transform: rotate(180deg);
      transform: rotate(180deg);
      span {
        background: #fff;
        width: 30px;
      }
    }
  }
}
.main_contents {
  padding-top: 116px;
}
css

@charset "UTF-8";
*, *::before, *::after {
  -webkit-box-sizing: border-box;
          box-sizing: border-box;
}

#global-navi {
  background: #333;
  position: fixed;
  top: 0;
  right: 0px;
  width: 100%;
}

#wrapper nav ul li {
  display: inline-block;
  font-size: 16px;
  padding: 30px 20px;
}

#wrapper nav ul li a {
  text-decoration: none;
  color: #ddd;
}

/*スマホ画面でハンバーガーメニューの形にする*/
@media screen and (max-width: 600px) {
  #wrapper nav {
    position: fixed;
    top: 0;
    right: -300px;
    width: 300px;
    height: 100%;
    padding-top: 50px;
    background: #333;
    font-size: 16px;
  }
  #wrapper nav ul li {
    display: block;
    padding: 20px 28px;
  }
  #wrapper nav ul li a {
    text-decoration: none;
    color: #ddd;
  }
  #wrapper .btn-gnavi {
    position: fixed;
    top: 20px;
    right: 20px;
    width: 30px;
    height: 24px;
    z-index: 2;
    cursor: pointer;
    -webkit-transition: all 400ms;
    transition: all 400ms;
  }
  #wrapper .btn-gnavi span {
    position: absolute;
    width: 30px;
    height: 4px;
    background: #666;
    border-radius: 10px;
    -webkit-transition: all 400ms;
    transition: all 400ms;
  }
  #wrapper .btn-gnavi span:nth-child(1) {
    top: 0;
  }
  #wrapper .btn-gnavi span:nth-child(2) {
    top: 10px;
  }
  #wrapper .btn-gnavi span:nth-child(3) {
    top: 20px;
  }
  #wrapper .btn-gnavi.open {
    -webkit-transform: rotate(180deg);
    transform: rotate(180deg);
  }
  #wrapper .btn-gnavi.open span {
    background: #fff;
    width: 24px;
  }
}

.main_contents {
  padding-top: 116px;
}
/*# sourceMappingURL=css_hamburger2.css.map */
jquery

$(function(){
    $(".btn-gnavi").on("click", function(){
        // ハンバーガーメニューの位置を設定
        var rightVal = 0;
        if($(this).hasClass("open")) {
            // 位置を移動させメニューを開いた状態にする
            rightVal = -300;
            // メニューを開いたら次回クリック時は閉じた状態になるよう設定
            $(this).removeClass("open");
        } else {
            // メニューを開いたら次回クリック時は閉じた状態になるよう設定
            $(this).addClass("open");
        }

        $("#global-navi").stop().animate({
            right: rightVal
        }, 200);
    });
});

 

実装内容の解説

htmlのhead

CSSjQueryを使えうようにしています。

jQueryはネットワーク上のあるライブラリを参照する形式です。

 

htmlのbody

btn-gnaviの部分

スマホハンバーガーメニュー部分を定義。

 

global-naviの部分

ディスプレイが600px以上の時

 ・ページの最上部に横に長いナビゲーションバー

 

ディスプレイが600px以下の時

 ・ページ右上に小さいナビゲーションボックス

 

scssの@media screenまで

position: fixedでナビゲーションバーを固定している。

liの中でdisplay: inline-boxを指定する事で、横並びにしている。

tex-decrationでリンクの下線を消している。

 

scssの@media screen以降

navの部分

・top 0; right -300px;とする事で、ページの外にナビゲーションを配置する。

・クリックした時にright 0;とする事でナビゲーションを表示させる(詳しくはjQueryで解説)

・height: 100%とする事で、高さが親ブロックのwrapと同じになる。wrapも高さを指定していないので、ページの上から下まで全てになる。

・display: block;とする事で、縦に並べている。通常デフォルトではblockだが、前にinline-blockを指定して横並びにしていたので、元に戻している。

 

btn-gnaviの部分

ハンバーガーメニューを表現している部分。

・top: 20px; right: 30px;で右上にハンバーガーメニューを表示させている。

・height: 24pxはハンバーガーメニューの横棒3本の幅とその隙間から計算されている。

・z-indexはハンバーガーメニューを表示させる高さを示している。数字が大きいほど高い。ここで2以上を指定しないと、jQueryを起動した時にハンバーガーメニューが表示されなくなってしまう。

・transitionでハンバーガーメニューをクリックした時のナビゲーションボックスが表示される速度を決定している。数字を大きくする遅く出現する。

 

spanの部分

・height: 4px;とする事で、ハンバガーメニューの横棒の太さを定義。

・border-radiusで横棒に丸みを持たせている。

・nth-childでハンバーガーメニューの3本の棒の位置を示している。3本目が位置が20pxであり、幅が4pxなので、結果的に全体の高さは24pxとなる。

 

.btn-gnavi.openの部分

ハンバーガーメニューをクリックする事で、jQueryでclass="open"が付与される。すると回転する。

・background: #fffでハンバーガーメニューが白になる。

 

jQuery

ハンバーガーメニューをクリックした時の処理を記述

・openがある時=すでにナビゲーションボックスが表示されている時、class="open"を消して、right: -300pxを設定して、ボックスをページの外に移動させる。

・openがない時、class="open"、right: 0を設定して、ボックスを表示させる。