今回はBootstrapやjQueryを使わず、
HTMLとCSS、純粋なJavaScriptのみで実装するハンバーガーメニューの作り方を解説します。
完成品のサンプル
以下は実際に作成したハンバーガーメニューのサンプルです。
超丁寧にコード内に解説コメントを入れているので、そのままコピペで使ってもらえます。
最高ですやん
See the Pen js-hamburger2 by takosan (@Yukiwebcreate) on CodePen.
必要な部分を自分で修正できる人はそのまま使ってください。
コードの解説や、どのようにして作成するかを見たい人は続きを読んでください。
コードの解説
今回のコードは、
・PCの場合は横並びのメニュー
・スマホ表示(今回は767px以下)の時だけメニューがハンバーガーメニューに格納される
・ハンバーガーボタンを押すとメニューは右からスライドで出てくる
・ハンバーガーアイコンはメニューが出ている時×印に変わる
という仕様です。
それではHTML、CSS、JSのコードの重要ポイントを解説していきましょう。
まずはHTMLから
<nav class="navbar">
<!-- ロゴ部分、ここに画像やテキストロゴを挿入可能 -->
<div class="logo">Logo画像文字</div>
<!-- モバイルメニューのトグルボタン -->
<div class="menu-toggle" id="mobile-menu">
<span class="bar"></span>
<span class="bar"></span>
<span class="bar"></span>
</div>
<!-- ナビゲーションリンクのリスト -->
<ul class="nav-list">
<li><a href="#">HOME</a></li>
<li><a href="#">ABOUT</a></li>
<li><a href="#">CONTACT</a></li>
</ul>
</nav>
今回は<nav>要素に全てを入れ込んであります。
ご自身のコードに持っていくときは適宜<header>や<div>タグなどに書き換えて使うなど調整してください。
重要な部分としてはul要素にメニューを格納して、mobile-menu要素で開閉ボタンを設置しているということです。
空の<span>タグは、ハンバーガーメニューの「≡」みたいなマークをCSSで描画するためだけのタグですので、
HTMLでは中身は必要ありません。(CSSによって中身を描画します)
続いてCSSを見ていきましょう。
全体のCSSを貼ると長くなるので、全体は上記サンプルのCSSウィンドウをご覧ください。
ここでは、重要な部分の解説をしていきます。以下は重要な部分だけを抜き出したCSSです。
/* 重要部分のみ抽出したCSSです */
.navbar {
display: flex; /* フレックスボックスを使用 */
justify-content: space-between; /* アイテムをスペースで均等に分割 */
align-items: center; /* 中央揃え */
background-color: #333; /* 背景色 */
color: white; /* 文字色 */
padding: 10px 20px; /* 内部余白 */
height: 50px; /* ナビバーの高さ */
}
.logo {
font-size: 24px; /* ロゴサイズ */
font-weight: bold; /* ボールド体 */
}
.nav-list {
list-style: none; /* リストスタイル無し */
display: flex; /* 水平表示 */
margin: 0; /* 外部余白なし */
}
.nav-list li {
padding: 0 15px; /* 各アイテムの内部余白 */
}
.nav-list a {
text-decoration: none; /* アンダーラインなし */
color: white; /* リンク色 */
}
/* モバイルメニュー用スタイル */
.menu-toggle {
display: none; /* デフォルトでは非表示 */
flex-direction: column; /* 垂直方向のスタック */
cursor: pointer; /* カーソルをポインタに設定 */
}
.menu-toggle .bar {
height: 3px; /* 棒の高さ */
width: 25px; /* 棒の幅 */
margin: 3px 0; /* 棒の間隔 */
background-color: white; /* 棒の色 */
transition: 0.3s; /* アニメーションの速さ */
}
/* メディアクエリでモバイル対応 */
@media (max-width: 768px) {
.nav-list {
position: absolute; /* 絶対位置 */
right: -100%; /* 初期位置は右外 */
top: 70px; /* 上部からの距離 */
flex-direction: column; /* 垂直方向のスタック */
background-color: #333; /* 背景色 */
width: 200px; /* 幅 */
height: 100%; /* 高さ */
justify-content: flex-start; /* 開始点から配置 */
padding-top: 20px; /* 上部の内部余白 */
transition: 0.3s; /* 位置変更のアニメーション時間 */
}
.nav-list li {
padding: 15px; /* リストアイテムの余白 */
}
.menu-toggle {
display: flex; /* モバイルでは表示 */
}
.nav-active {
right: 0; /* アクティブ時は右端に */
}
.toggle .bar:nth-child(1),
.toggle .bar:nth-child(3) {
transform: translateX(-5px); /* X記号のための変形 */
}
.toggle .bar:nth-child(1) {
transform: rotate(-45deg) translate(-6px, 7px);
}
.toggle .bar:nth-child(2) {
opacity: 0; /* 中央の棒を透明に */
}
.toggle .bar:nth-child(3) {
transform: rotate(45deg) translate(-5px, -7px);
}
}
CSSではPCでのスタイリングを先に行っています。(モバイルファーストでコーディングしたい方は適宜ご調整を・・・)
それぞれの役割
ナビゲーションバーは.navbarとしてロゴ画像やメニュー全てを格納しています。
ロゴ画像は要らない人もいるので、不要なら消してOKです。特に説明も不要かと思います。
.navbarの中の.nav-listは、ul要素でメニューを格納しているクラスです。
PCでは横並びでメニューが横一列に並ぶようにしています。
スマートフォンではこの部分がハンバーガーメニューに変身します。
続いて、
#mobile-menuはハンバーガーメニューの表示非表示を切り替えるボタン的な要素です。
同じ要素にclassで.menu-toggleという名前もつけており、PCではdisplay:noneで非表示にしています。
スマホ表示(767px以下)にしたときに、display:flexで表示するようにしています。
メニューはどこに消えた?(スマホ表示のとき)
スマホ表示になった際、メニューはどこに隠れたかというと、
right:-100%により画面外へ吹き飛ばしています。
#mobile-menuボタンが押された時に、right:0で正規の位置へ戻ってくるという仕組みです。
どんな仕組み?JavaScriptのコードを見てみよう
前述の仕組みはJavaScriptとCSSを組み合わせて定義しています。
簡単にいうとCSSで.nav-activeというクラスにright:0;を設定しておき、
JavaScriptによってそのクラスを付与したり、外したりしているのです。
実際にJavaScriptのコードを見ていきましょう。
// モバイルメニューのトグル要素とナビゲーションリストの要素を取得
const mobileMenu = document.getElementById("mobile-menu");
const navList = document.querySelector(".nav-list");
// トグルボタンのクリックイベントリスナー
mobileMenu.addEventListener("click", () => {
// ナビゲーションリストに 'nav-active' クラスをトグル
navList.classList.toggle("nav-active");
// メニュートグル自体に 'toggle' クラスをトグルして、アイコンの形状変更を行う
mobileMenu.classList.toggle("toggle");
});
JavaScriptのコードは簡単です。
ボタンが押されたかどうかを判定したいのでmobileMenuを定義しています。
そしてクラスを付与する対象が必要なのでnavListを定義しています。
あとはボタンのクリックに応じて、上記の.nav-activeというクラスをつけたり消したりしているだけです。
解説としては以上になります。
さいごに
ほとんどCSSで制御しており、jQueryやBootstrapなどのライブラリやフレームワークに頼る必要がないため、
導入もしやすく、メンテナンス性も高いです。
こういった機能をさらっと作成できると、Web制作者、フロントエンドとしてはワンランクアップですね。
是非ご活用ください。
▼JavaScriptオススメ書籍▼
こちらの書籍は、
・様々なJavaScriptコードレシピがあり辞典のように使える
・JavaScript初心者でもわかりやすくコードが書かれている
・約600ページと圧倒的ボリューム
など一冊持っていれば「あれどうやるんだっけ?」というのを解決してくれるのでおすすめです。
見てみます!