jquery ハンバーガーメニューを作ってみよう(基本〜応用の入り口まで)

# 今日の目標
ハンバーガーメニューを作れるようになる

## 最終制作物はこちら

[![Image from Gyazo](https://i.gyazo.com/e4bf1ffdc10c3ef1aa461ec109eafc94.gif)](https://gyazo.com/e4bf1ffdc10c3ef1aa461ec109eafc94)

画面をスクロールしても常に左上で固定　↓
[![Image from Gyazo](https://i.gyazo.com/0b3f4abadcf6ee24605dbdb04abcd78a.gif)](https://gyazo.com/0b3f4abadcf6ee24605dbdb04abcd78a)
## ハンバーガメニュー作成の流れ
１、まず、HTMLでハンバーガーメニューのボタンとなる要素をつくります。
2、次にjQueryで、「ボタンをクリックしたとき」に、「指定したHTMLタグにクラスを追加」させます。
3、追加したクラスにCSSを当てて、要素に動きを与えて行きます。

まずはHTMLで枠組みを作ります

```html:HTML
<span class="nav_toggle">
    <i></i>
    <i></i>
    <i></i>
</span>
<nav class="nav">
    <ul class="nav_menu_ul">
        <li class="nav_menu_li"><a href="#">TOP</a></li>
        <li class="nav_menu_li"><a href="#">ABOUT</a></li>
        <li class="nav_menu_li"><a href="#">BLOG</a></li>
        <li class="nav_menu_li"><a href="#">CONTACT</a></li>
    </ul>
</nav>

```

１〜５行目

```
<span class="nav_toggle">
    <i></i>
    <i></i>
    <i></i>
</span>
```
この部分がハンバーガーメニューのボタンになります。
iタグでハンバーガメニューの線を表現します。

６〜１３行目

```html:
<nav class="nav">
    <ul class="nav_menu_ul">
        <li class="nav_menu_li"><a href="#">TOP</a></li>
        <li class="nav_menu_li"><a href="#">ABOUT</a></li>
        <li class="nav_menu_li"><a href="#">BLOG</a></li>
        <li class="nav_menu_li"><a href="#">CONTACT</a></li>
    </ul>
</nav>
```
この部分がハンバーガーメニューのメニューリストになります。
ボタンのクリックによって、表示/非表示が切り替わる部分です。

次にjquery

```javascript:jquery
$(function(){
$('.nav_toggle').on('click', function () {
    $('.nav_toggle, .nav').toggleClass('show');
});
})
```
jQueryの解説

```javascript

$('.nav_toggle').on('click', function ()
```
ここでは、なんの動作をトリガーにしてjQueryが動くのかを定義しています。
.nav_toggle（ボタン）　をクリックすると後続の{}内の記述を実行します。
(‘.nav_toggle’)　ここには、3本の線の親要素のクラス名を記述します。

```
$('.nav_toggle, .nav').toggleClass('show');
```
ボタンをクリックしたことで変化させたい要素のクラス名を表示します。

.nav_toggle（ボタン）　→　クリックで3本線を  にする
.nav（メニューリスト）→　表示/非表示の切り替え
なので、.nav_toggle（ボタン）　と　.nav（メニューリスト）　に、　showというクラスを付与する

Googleデベロッパーで見てみると
[![Image from Gyazo](https://i.gyazo.com/9eff980f81abe425a5fef6f5194ffecb.gif)](https://gyazo.com/9eff980f81abe425a5fef6f5194ffecb)
クリックの動作を拾って、指定した要素にshowが追加されています。
jQueryの作業はこれで終了です。
.showがあるときと、ないときのCSSを記述して要素に動きを持たせます。
## CSS
CSSはパーツとその状態ごとに作成していきます
全部で以下の４パターンです。

ボタン
０１　クリックされる前
０２　クリック後（クラスに.showが追加されている）

メニューリスト
０３　クリックされる前
０４　クリック後（クラスに.showが追加されている）

メニューが表示されている状態＝ボタンがクリックされたとき＝.show が要素に追加されているとき ということになります。
### CSS クリック前

```css:
.nav_toggle {
    display: block;
    position: relative;
    width: 1.75rem;
    height: 1.5rem;
}
.nav_toggle i {
    display: block;
    width: 100%;
    height: 2px;
    background-color: #333;
    position: absolute;
    transition: transform .5s, opacity .5s;
}
.nav_toggle i:nth-child(1) {
    top: 0;
}
.nav_toggle i:nth-child(2) {
    top: 0;
    bottom: 0;
    margin: auto;
}
.nav_toggle i:nth-child(3) {
    bottom: 0;
}
```
ボタン【クリック前】のCSS解説
.nav_toggle＝3本線の親要素
この要素を基準にして内包する線の位置を定義

.nav_toggle i＝3本線
3本線の本体となる部分
transition: transform .5s, opacity .5s; で、変化させるプロパティと変化にかかる時間を定義
transformとopacityを.5秒かけて変化させています
ボタンクリック時のアニメーションの速度を調整したい場合は、ここの数値を変更してください

.nav_toggle i:nth-child(1)＝3本線の一番上
.nav_toggle i:nth-child(2)＝3本線の真ん中
.nav_toggle i:nth-child(3)＝3本線の一番下
それぞれの線の位置を定義

## CSSクリック後

```css:
.nav_toggle.show i:nth-child(1) {
    transform: translateY(10px) rotate(-45deg);
}
.nav_toggle.show i:nth-child(2) {
    opacity: 0;
}
.nav_toggle.show i:nth-child(3) {
    transform: translateY(-12px) rotate(45deg);
}
```
ボタンのCSS 【クリック後　.showが追加されている】CSS解説
ボタンがクリックされて、.show が要素に付与されたときに当たるCSSです。

.nav_toggle.show i:nth-child(1)＝3本線の一番上
.nav_toggle.show i:nth-child(3)＝3本線の一番下
になるようにそれぞれの線の傾きと縦方向の位置を定義
transition: transform .5s, opacity .5s;で変化させるプロパティと、変化にかかる時間を定義しているので、
.5秒かけて線が傾いていきます。

.nav_toggle.show i:nth-child(2)＝3本線の真ん中
opacity:1; →opacity: 0;＝opacityにもtransitionで変化にかかる時間を指定しているので、ボタンが押されると.5秒かけて非表示になります。

メニューリストのCSS【クリック前】

```css:
nav {
    position: fixed;
    top: 3rem;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 1rem;
    opacity: 0;
    visibility: hidden;
    transition: opacity .5s, visibility .5s;
}
```

ボタンのCSS【クリック前】CSS解説
transition: opacity .5s, visibility .5s; で、変化させるプロパティと変化にかかる時間を定義

メニューリストのCSS【クリック後　.showが追加されている】

```css:
.nav.show {
    opacity: 1;
    visibility: visible;
}
```
メニューリストのCSS【クリック後　.showが追加されている】CSS解説
.navのとき opacity: 0; → .navi.showのとき opacity: 1;
transition で指定した通り.5秒かけて変化します。

visibility: hidden; → visibility: visible;
こっちも同様にtransitionで指定した通り.5秒かけて変化します。

[![Image from Gyazo](https://i.gyazo.com/bba34357a79e9f65b598584c90733ed7.gif)](https://gyazo.com/bba34357a79e9f65b598584c90733ed7)

jQueryってなに…など、わからないことが多くて戸惑ってしまうと思います。
作ってみると仕組みはとてもシンプルで、jQueryを３行書いて、クラスを付与して、あとはHTMLとCSSだけで作ることができるので一度理解してしまえば今後はハンバーガーメニューだけでなく、画像のフェードインや、ローディング画面など、他にもいろいろなところで応用がきくので、一度作ってみるといいかもしれません。

# 応用バージョン

HTMLは上記のバージョンと変わりません(いきなりhamlですみません)

```haml:html
%ul.navbar.navbar-light.bg-light.static-top
  #navArea
    
    %nav-a
     .inner
      %ul
        %li
          =link_to "TOPへ戻る",root_path
        %li
          =link_to "講師一覧ページへ",teachers_path
        %li
          %a{:href => "#index2"} カウンセリングについて
        %li
          %a{:href => "#index3"} 料金について
        %li
          %a{:href => "#"} 講師マッチングシステム
        %li
          %a{:href => "#"} 利用者の声 
    .toggle_btn
      %span
      %span
      %span
      
    #mask
```
3本線は`%span`で表現します

クラス名ですが`nav`だと　他のCSSと競合する恐れがあるので　`nav-a`としています。


CSS

アニメーションをつけてみました。
@keyframesとanimationについてはこちらの記事をご覧ください
[CSSでアニメーションを作ってみよう](https://qiita.com/keitah/items/30b12d33a7c5fbd990af)

```scss:css

nav-a {
  display: block;
  position: fixed;
  top: 0;
  left: -300px;
  bottom: 0;
  width: 300px;
  background: #ffffff;
  overflow-x: hidden;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  transition: .5s;
  z-index: 3;
}
.open nav-a {
  left: 0;
}
nav-a .inner {
  padding: 25px;
}
nav-a .inner ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
nav-a .inner ul li {
  position: relative;
  margin: 0;
  border-bottom: 1px solid #333;
}
nav-a .inner ul li a {
  display: block;
  color: #333;
  font-size: 14px;
  padding: 1em;
  text-decoration: none;
  transition-duration: 0.2s;
}
nav-a .inner ul li a:hover {
  background: #e4e4e4;
}
@media screen and (max-width: 767px) {
  nav-a {
    left: -240px;
    width: 240px;
  }
}
/*============
@keyframes
=============*/
@keyframes equalizer01 {
  0% {
    width: 70%;
  }
  10% {
    width: 50%;
  }
  20% {
    width: 100%;
  }
  30% {
    width: 10%;
  }
  40% {
    width: 50%;
  }
  50% {
    width: 70%;
  }
  60% {
    width: 50%;
  }
  70% {
    width: 10%;
  }
  80% {
    width: 100%;
  }
  90% {
    width: 10%;
  }
  100% {
    width: 70%;
  }
}
@keyframes equalizer02 {
  0% {
    width: 30%;
  }
  10% {
    width: 20%;
  }
  20% {
    width: 40%;
  }
  30% {
    width: 10%;
  }
  40% {
    width: 20%;
  }
  50% {
    width: 30%;
  }
  60% {
    width: 20%;
  }
  70% {
    width: 10%;
  }
  80% {
    width: 40%;
  }
  90% {
    width: 10%;
  }
  100% {
    width: 30%;
  }
}
/*============
.toggle_btn
=============*/
.toggle_btn {
  display: block;
  position: fixed;
  top: 30px;
  left: 30px;
  width: 60px;
  height: 30px;
  transform: translate(0, 0);
  transition: all .5s;
  cursor: pointer;
  z-index: 3;
}
.open .toggle_btn {
  left: 330px;
}
.toggle_btn span {
  display: block;
  position: absolute;
  left: 0;
  width: 40px;
  height: 6px;
  background-color: rgb(219, 52, 116);
  transition: all .5s;
}
.toggle_btn span:nth-child(1) {
  top: 5px;
  width: 60px;
  animation: equalizer01 7000ms infinite;
}
.toggle_btn span:nth-child(2) {
  top: 15px;
  width: 50px;
  animation: equalizer02 5000ms infinite;
  animation-delay: 0.33s;
}
.toggle_btn span:nth-child(3) {
  top: 25px;
  width: 60px;
  animation: equalizer02 5000ms infinite;
}

.open .toggle_btn span {
  background-color: #fff;
  width: 30px;
}
.open .toggle_btn span:nth-child(1) {
  transform: translate(0, 10px) rotate(-45deg);
  animation: unset;
}
.open .toggle_btn span:nth-child(2) {
  opacity: 0;
  animation: unset;
}
.open .toggle_btn span:nth-child(3) {
  transform: translate(0, -10px) rotate(45deg);
  animation: unset;
}

@media screen and (max-width: 767px) {
  .open .toggle_btn {
    left: 260px;
  }
}
/*============
#mask
=============*/
#mask {
  display: none;
}
.open #mask {
  display: block;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #000;
  opacity: .8;
  z-index: 2;
  cursor: pointer;
  transition: all .5s;
}
/*============
main
=============*/
main {
  padding: 50px;
}
main h1 {
  font-family: 'Open Sans', sans-serif;
  font-weight: 400;
  text-align: center;
}
/*============
body
=============*/
body {
  font-family: 'Open Sans', sans-serif;
  font-weight: 400;
}
```
一応ポイントは　ハンバーガメニューを開いた時にメインエリアを暗くしているところです。
ハンバーガーメニューがopenの時に　`#mask`が作動します。


## jquery


```javascript:humburger.js

$(function () {
  var $nav = $('#navArea');
  var $btn = $('.toggle_btn');
  var $mask = $('#mask');
  var open = 'open'; // class
  // menu open close
  $btn.on('click', function () {
    if (!$nav.hasClass(open)) {
      $nav.addClass(open);
    } else {
      $nav.removeClass(open);
    }
  });
  // mask close
  $mask.on('click', function () {
    $nav.removeClass(open);
  });
})

```

[![Image from Gyazo](https://i.gyazo.com/e4bf1ffdc10c3ef1aa461ec109eafc94.gif)](https://gyazo.com/e4bf1ffdc10c3ef1aa461ec109eafc94)

いろいろ　イジってかっこよくデザインしてみてください！

檜垣慶太
https://github.com/higakikeita