10
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Posted at

今日の目標

ハンバーガーメニューを作れるようになる

最終制作物はこちら

Image from Gyazo

画面をスクロールしても常に左上で固定 ↓
Image from Gyazo

ハンバーガメニュー作成の流れ

1、まず、HTMLでハンバーガーメニューのボタンとなる要素をつくります。
2、次にjQueryで、「ボタンをクリックしたとき」に、「指定したHTMLタグにクラスを追加」させます。
3、追加したクラスにCSSを当てて、要素に動きを与えて行きます。

まずは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>

1〜5行目

<span class="nav_toggle">
    <i></i>
    <i></i>
    <i></i>
</span>

この部分がハンバーガーメニューのボタンになります。
iタグでハンバーガメニューの線を表現します。

6〜13行目

<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

jquery
$(function(){
$('.nav_toggle').on('click', function () {
    $('.nav_toggle, .nav').toggleClass('show');
});
})

jQueryの解説


$('.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
クリックの動作を拾って、指定した要素にshowが追加されています。
jQueryの作業はこれで終了です。
.showがあるときと、ないときのCSSを記述して要素に動きを持たせます。

CSS

CSSはパーツとその状態ごとに作成していきます
全部で以下の4パターンです。

ボタン
01 クリックされる前
02 クリック後(クラスに.showが追加されている)

メニューリスト
03 クリックされる前
04 クリック後(クラスに.showが追加されている)

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

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クリック後

.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【クリック前】

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が追加されている】

.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

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

応用バージョン

HTMLは上記のバージョンと変わりません(いきなり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でアニメーションを作ってみよう

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

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://github.com/higakikeita

10
9
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
10
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?