ハンバーガーメニューについて考えてみた
レスポンシブなハンバーガーメニューを作りたくて、色々調べていました。
ただ導入するだけなら、コードのコピペで済むんでしょうが、実装内容をきちんと理解したいと思いこの記事を書いています。
以下の記事で紹介さ入れているコードについて、考察しています。
まずはコード。これを書けばとりあえず動く。
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
・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を設定して、ボックスを表示させる。