レスポンシブ対応!世界一簡単なハンバーガーメニューの実装法(コピペOK)

こんにちは、北陸のwebコーダーdaimaです。
本日は、ナビゲーションをコンパクトに纏められる
おしゃれなハンバーガーメニューの実装方法をご紹介します。
まずは下記のデモページをご覧ください。

今回はこのように、至ってシンプルな ハンバーガーメニューを作成します。
動作確認済ブラウザはChrome、IE、FireFox、safariの
最新バージョン(記事執筆時点)です。

ソースコードと解説

<div class="header">
  
  <div class="el_humburger">
    <span class="top"></span>
    <span class="middle"></span>
    <span class="bottom"></span>
  </div>
    
  <div id="navigation" class="navigation">
    <div class="navigation_screen">
      <nav class="navigation_wrapper">
        <div class="navigation_item"><a href ="#">CONTENT</a></div>
        <div class="navigation_item"><a href ="#">CONTENT</a></div>
        <div class="navigation_item"><a href ="#">CONTENT</a></div>
        <div class="navigation_item"><a href ="#">CONTENT</a></div>
        <div class="navigation_item"><a href ="#">CONTENT</a></div>
        <div class="navigation_item"><a href ="#">CONTENT</a></div>
        <div class="navigation_item"><a href ="#">CONTENT</a></div>
        <div class="navigation_item"><a href ="#">CONTENT</a></div>
        <div class="navigation_item"><a href ="#">CONTENT</a></div>
        <div class="navigation_item"><a href ="#">CONTENT</a></div>
        <div class="navigation_item"><a href ="#">CONTENT</a></div>
        <div class="navigation_item"><a href ="#">CONTENT</a></div>
        <div class="navigation_item"><a href ="#">CONTENT</a></div>
        <div class="navigation_item"><a href ="#">CONTENT</a></div>
        <div class="navigation_item"><a href ="#">CONTENT</a></div>
        <div class="navigation_item"><a href ="#">CONTENT</a></div>
      </nav>
    </div>
  </div>
</div>

<div class="wrap">

  <div class="content">
    I LOVE HUMBURGUR MENU
  </div>
  
</div>

HTMLソースです。
ハンバーガーボタンとナビゲーションの
マークアップを行っています。

/*基本レイアウトの調整*/
body {
  margin: 0;
}

.wrap {
  padding: 60px 0 0 0;
}

.content {
  text-align: center;
  font-size: 22px;
  color: #bf86ce;
  height: 2000px;
  padding: 60px;
  background-color: #f8e0f7;
}

/*ハンバーガーボタン*/

.header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 60px;
  background-color: #be9dc9;
}

.el_humburger {
  position: absolute;
  top: 18px;
  right: 18px;
  width: 26px;
  height: auto;
  padding-top: 1px;
  box-sizing: border-box;
  z-index: 10000;
  transition: all 0.2s ease-in-out;
  cursor: pointer;
  pointer-events: auto;
}

.js_humburgerOpen .el_humburger {
}

.el_humburger > span {
  display: block;
  width: 100%;
  margin: 0 auto 6px;
  height: 3px;
  background: #000;
  transition: all 0.2s ease-in-out;
  &:last-child {
    margin-bottom: 0;
  }
  .js_humburgerOpen & {
    background: #000;
  }
}

.js_humburgerOpen .el_humburger > span.top {
  transform: translateY(9px) rotate(-45deg);
}

.js_humburgerOpen .el_humburger > span.middle {
  opacity: 0;
}

.js_humburgerOpen .el_humburger > span.bottom {
  transform: translateY(-9px) rotate(45deg);
}

.el_humburgerButton.el_humburgerButton__close {
  top: 2%;
  right: 2%;
}

.el_humburgerButton__close > span {
  display: block;
  width: 35px;
  margin: 0 auto;
  height: 4px;
  background: #fff;
}

.el_humburgerButton__close > span.el_humburgerLineTop {
  transform: translateY(5px) rotate(-45deg);
}

.el_humburgerButton__close > span.el_humburgerLineBottom {
  transform: translateY(-6px) rotate(45deg);
}

/*ナビゲーション*/

.navigation {
  display: none;
  &.js_appear {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    display: block;
    z-index: 9999;
  }
}

.navigation_screen {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background-color: rgba(255, 255, 255, 0.96);
  z-index: 0;
  margin-top: 0px;
  padding-top: 0px;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
}

.navigation_wrapper {
  padding: 80px 0 0 0;
  text-align: center;
}

.navigation_item {
  font-ize: 18px;
  margin-bottom: 20px;
}

.navigation_item > a {
  color: #000;
  text-decoration: none;
}

.js_fixed {
	position: fixed;
	width: 100%;
	height: 100%;
}

CSSソース。
ハンバーガーボタンの動作と
ナビゲーション表示時の
レイアウト指定を行っています。

ここでのミソは、
.navigation_screenに記載されている
-webkit-overflow-scrolling: touch;というプロパティ。
これを指定しておくと、
スマホでナビゲーション内部を
スワイプしたときの動作が滑らかになります。

//ハンバーガーメニュー
$(function(){
  $('.el_humburger').on('click',function(){
    spNavInout();
  });
});

//spナビ開く処理
function spNavIn(){
  $('body').removeClass('js_humburgerClose');
  $('body').addClass('js_humburgerOpen');
  $(".navigation").addClass("js_appear");
  $(".navigation").css({opacity:0});
  $(".navigation").animate({
    opacity: 1
  },200);
  scrollBlocker(true);
}

//spナビ閉じる処理
function spNavOut(){
  $(".navigation").animate({
    opacity: 0
  },200)
  $('body').removeClass('js_humburgerOpen');
  $('body').addClass('js_humburgerClose');
  setTimeout(function(){
    $(".navigation").removeClass("js_appear");
  },200);
  scrollBlocker(false);
}

//spナビ開閉処理
function spNavInout(){
  if($('body.spNavFreez').length){
    return false;
  }
  if($('body').hasClass('js_humburgerOpen')){
   spNavOut();
  } else {
   spNavIn();
  }
}

//ナビ向けスクロール無効化処理

var scrollBlockerFlag;

function scrollBlocker(flag){
  if(flag){
    scrollpos = $(window).scrollTop();
    $('body').addClass('js_fixed').css({'top': -scrollpos});
    scrollBlockerFlag = true;
  } else {
    $('body').removeClass('js_fixed').css({'top': 0});
    window.scrollTo( 0 , scrollpos );
    scrollBlockerFlag = false;
  }
}

そして最後がjavascipt(jQuery)ソース。
ここでやっていることは大きく分けて次の2つです。

1.bodyにナビゲーション判別用のクラス「js_humburgerOpen」があるか判定し、
なければクラスの追加とナビゲーションの表示処理、
あればクラスの削除とナビゲーションの非表示処理を行う。

2.自作関数scrollBlockerで、
ナビゲーションが開いているときに、
body及びhtmlがスクロールしないように固定する。

特に2の部分で少し凝った処理をしていて、
まずナビオープン時のy位置を取得し、
次にbodyにクラス「js_fixed」を付与して
bodyのpositionを一時的にfixedに変更しています。

そして最後にcssのtopでbodyのy位置を
ナビオープン時のスクロール量分ずらし、
見た目上の表示位置を合わせることによって
スクロールの固定を実現しているのです。

この処理上、ナビオープン時の
yスクロール量は必ず0になります。
ですので、当ナビを導入して
万が一他の処理に不具合が起きた場合は
まずこの点を疑ってみてください。

さいごに

ハンバーガーメニューの実装処理、
上手くいきましたでしょうか。

ハンバーガーメニューはおしゃれで大変便利ですが、
ユーザビリティの観点から見ると、
年配の方には一見してメニューだと
分かり辛い
という指摘もしばしば聞かれます。

ですので、年配のユーザーが多い
サイトに導入する場合は
ハンバーガーの直下に「メニュー」の
表記を足す
などのひと工夫を行うと良いでしょう。

今回ご紹介したのは、あくまでも
必要最低限の枠組みだけですので、
仕組みが理解出来たらぜひ、
あなただけのオリジナルのメニューに カスタマイズしてみてください。

それでは!

コメント

  1. 赤堀 竜海 より:

    初めまして!質問がありコメントさせていただきました。

    sp時にハンバーガーメニューを取り入れたいのですが、ハンバーガーメニューをクリックしてもnavigationが表示されません、、、

    もし思い当たる原因などありましたら教えていただけると幸いです。

    よろしくお願いいたします。

    • daima より:

      赤堀様、コメントありがとうございます。
      管理人のdaimaです、お返事遅くなりごめんなさい。

      navigationが表示されないということですが
      原因の特定にはこちらで実際のコードを確認する必要があります。

      ですので、もし差し支えなければ
      コードデータかサイトURLをフォームからお伝えください。