コピペで実装!jQueryでレスポンシブなハンバーガーメニューを実装する

  • LINEで送る

ハンバーガーメニューとは,三本線のボタンのことです.クリックまたは,タップするとメニューが表示されます.一般的にはスマートフォン用のデザインで採用されることが多く,画面領域の有効活用ができます.もちろんPC等の画面が広いデバイスでも使用されることはありますが,今回はスマホ用の画面で,ハンバーガーメニューを表示し,大きい画面ではメニューを横並びにヘッダーに表示させます.これはCSSのみでは難しいので,jQueryを交えて実装していきます.

サンプルページ

今回作るレスポンシブなハンバーがメニューは以下のとおりです.

レスポンシブ
ハンバーガーメニュー
ハンバーガーメニュー

ハンバーガーメニューの作り方や,そのアニメーション方法はこのサイトが非常にわかりやすかったため,参考にしています.詳しくはそちらをご覧ください.今回はコードだけ紹介します.

ハンバーガーメニューのHTMLとCSS,jQueryのソースコードは以下のとおりです.

ハンバーガーメニューのみのHTML

<div class="btn-trigger" id="btn">
    <span></span>
    <span></span>
    <span></span>
</div>

ハンバーガーメニューのみのCSS

.btn-trigger {
    position: absolute;
    top: 50%;
    right: 20px;
    width: 34px;
    height: 28px;
    transform: translateY(-50%);
    cursor: pointer;
}
.btn-trigger span {
    position: absolute;
    left: 0;
    width: 100%;
    height: 4px;
    background-color: #383838;
    border-radius: 4px;
}
.btn-trigger, .btn-trigger span {
    display: inline-block;
    transition: all .5s;
    box-sizing: border-box;
}
.btn-trigger span:nth-of-type(1) {
    top: 0;
}
.btn-trigger span:nth-of-type(2) {
    top: 12px;
}
.btn-trigger span:nth-of-type(3) {
    bottom: 0;
}
#btn.active span:nth-of-type(1) {
    transform: translateY(12px) rotate(-45deg);
}
#btn.active span:nth-of-type(2) {
    left: 50%;
    opacity: 0;
    animation: active-btn-bar02 .8s forwards;
}
@keyframes active-btn-bar02 {
    100% {
        height: 0;
    }
}
#btn.active span:nth-of-type(3) {
    transform: translateY(-12px) rotate(45deg);
}

ハンバーガーメニューのみのjQuery

$('.btn-trigger').on('click', function(){
    $(this).toggleClass('active');
    return false;
});

jQueryのコードには「.btn-trigger」クラスに,「active」クラスがあるかないかでif文で場合分けを行い,処理を分岐させるコードを追加します.

それではハンバーガーメニューをクリックした時にメニューの内容を前面に表示する方法を見ていきましょう.

HTML(headerの内容)

<header id="page-header" role="banner">
    <div class="inner">
        <h1><img src="/img/tamotech-logo.png" alt=""></h1>
        <nav>
            <ul>
                <li><a href="https://tamontech.blog">Home</a></li>
                <li><a href="#">HTML</a></li>
                <li><a href="#">SCSS</a></li>
                <li><a href="#">jQuery</a></li>
                <li><a href="#">Information</a></li>
            </ul>
        </nav>
        <div class="btn-trigger" id="btn">
            <span></span>
            <span></span>
            <span></span>
        </div>
    </div>
</header>

ボタンを構成するspanタグの他に,リスト型のメニュー内容をulとliで作成しておきましょう.

SCSS(メニュー内容のレイアウト)

すべてのコードを表示させると長くなるので,一部重要な部分だけ表示させます.

header {
    width: 100%;
    height: 12vh;
    color: #1d1d1d;
    background:rgba(255,255,255,0.6);
    position: absolute;
    bottom: 0;
    
    .inner {
        height: 100%;
        margin: 0px 40px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        img {
            width: auto;
            height: 7vh;
        }
        nav {
            ul {
                list-style: none;
                display: flex;
                
                li {
                    margin: 0 20px;  
                    font-size: 17px;
}}}}}
@media (max-width: 760px){
    header {
        top: 0;
        height: 10vh;
        
        .inner {
            margin: 0 15px;
            justify-content: center;
            img {
                height: 5vh;
            }
            nav {
                position: fixed;
                top: 10vh;
                bottom: 0;
                right: 0;
                left: 0;
                visibility: hidden;
                opacity: 0;
                transition: 0.5s;
                background-color: rgba(0, 0, 0, 0.5);
                ul {
                    position: absolute;
                    top: 50%;
                    transform: translateY(-50%);
                    flex-direction: column;
                    align-items: flex-start;
                    li {
                        margin: 20px;
                        a {
                            font-size: 20px;
                            color: white;
}}}}}}}
@media (min-width: 761px){
    .btn-trigger {
        display: none;
    }
}

1行目から27行目までは,デスクトップバージョンの画面が広いレイアウトをしています.headerタグに{position:absolute}を設定し,{bottom:0}で一番下に配置するようにしています.またulタグに{display:flex}を設定して複数のliが横並びになるようにしています.

28行目から60行目はスマートフォン等の画面幅が狭いレイアウトを設定しています.「@media」を使って760px以下のレイアウトを指定しています.headerは{top:0}で上に配置し,navタグは画面いっぱいに{position:fixed}で固定させています.初期段階では表示しないので,{visibility: hidden}で隠しています.

61行目から65行目はデスクトップ用の761px以上で,ハンバーガーメニューが表示されないようにしています.重要な箇所は以上になります.あとはレイアウトの調整なので,この記事を参考にする場合は調整してください.

jQuery(メニューの表示・非表示)

jQueryのソースコードは先ほどのハンバーガーメニューに少し付け加えるだけです.

$('.btn-trigger').on('click', function(){
    $(this).toggleClass('active');
    if ($(this).hasClass('active')){
        $('nav').css({
            'visibility': 'visible',
            'opacity': 1
        });
    } else {
        $('nav').css({
            'visibility': 'hidden',
            'opacity': 0
        });
    }
    return false;
});

ハンバーガーボタンがクリックされ,activeクラスがあれば消去し,なければ追加する処理が先ほどのコードでした.これにnavタグの表示・非表示の処理を追加します.activeクラスがある場合,navタグのCSSに「’visibility’: ‘visible’」と「’opacity’: 1」を指定して表示させます.activeクラスがない場合,非表示にさせます.jQueryで行っている処理はこれだけです.

切り替わる速度はCSSの{transition:0.5s}で指定してあるので,ここでanimate()メソッドなどで指定する必要はありません.

これで今回の記事は終了です.Webページをスマホで見る場合は必ずハンバーガーメニューが使われていると言っても過言ではありません.メニューやハンバーガーボタンのアニメーションなどを変更してもおしゃれだと思います!

サンプルページはこちらからも閲覧できます.

サンプルページのソースコードはこちらからダウンロードできます.

SNSでもご購読できます。

コメント

  1. あきちゃん より:

    はじめまして。
    こちらの記事を参考にハンバーガーメニューを実装してみました。

    一つ、質問があります。
    同ページ内にリンクした場合、移動はしますがメニューが表示されたままなのですが、消える方法をご教示願えますでしょうか。

    1. tamon1028 より:

      返信遅くなってしまい申し訳ありません!コメントありがとうございます!

      ハンバーがメニューの要素に「active」クラスがあるかないかで,処理を分けています.ハンバーガーボタンをクリックして,「active」クラスがあれば消去し,なければ追加する処理を入れています.ページ内リンクの場合,ページが変わらないのでactiveクラスが残ったままになり,表示されっぱなしになっているのだと思います.

      この場合は,ページ内リンクをクリックした場合のみ,ナビゲーションメニューを非表示にする処理を追加してみてはどうでしょうか!
      ページ内リンクの要素にだけ,page_linkクラスを設定しておいて,

      $(‘.page_link’).on(‘click’,function(){
      $(‘nav’).css({
      ‘visibility’: ‘hidden’,
      ‘opacity’: 0
      });
        $(‘.btn-trigger’).removeClass(‘active’);
      });

      on()メソッドでクリックイベントを設定して,クリックされたら「nav」を非表示にします.
      最後にボタン形状を3本線に戻すために「btn-trigger」クラスから「active」クラスを除去します.
      他にもいろいろやり方はあると思います.もし何かわからないことや,他の方法も気になったらいつでもコメントしてください!
      ありがとうございます.

  2. Act より:

    はじめまして、こんにちは!
    レスポンシブの際このサイトのハンバーガーメニュー実装してみたのですが、
    ハンバーガーメニューを使用した後に画面を大きくしnav部分を表示させようとしたところ
    visibleがhiddenのまま画面が大きくなり、navが表示されない状態になります。
    実際サイトを使用する際にはそこまで問題ないと思うのですが、
    実装の際に動かしていると、なんとかならないかなーと思います。
    css,jquery初学者で自分では解決すこし難しいので、解決方法あったらご教授お願いします

    1. tamon1028 より:

      コメントありがとうございます!今確認したところ確かに画面を途中で広げると,visibility:hiddenが残ったままとなってしまい,メニューが消えてしまいますね...
      一般のユーザーが画面の大きさを途中で変えることは滅多にないので,あまり気にしなくてもいいですが,作っている側からすると気になりますね笑

      回避方法としてはレスポンシブの設定以外のところで,初期値として「visibility:visable」を
      「scssstyle.scss」の19行目と20行目の間に入れれば,常にメニューが表示されると思います!

      一度試してみてください!またなにかあればコメントください!

      1. Act より:

        scssのvisiblityをvisableにすると、レスポンシブ画面の時に最初からハンバーガーメニューが表示されてしまって、失敗していました。
        しかし、ハンバーガーメニューのブレイクポイントに@media min-widthでstyleにvisibility:visableを設定すると、Styleではvisibleが設定されているのですが、多分優先順位的にHTMLに直接かいてあるstyleが実行されて、visibility:hidden;が優先され実行されてしまいます…
        HTMLに書かれているところを変えないといけないのかなと思い、それならjqueryを編集しなければならないかなと、試行錯誤している状態です。またなにか案があれば、試してみたいと思います。よろしくお願いします

コメントを残す

*