この記事ではHTML,CSS,JavaScriptを用いた「ハンバーガーメニュー」の作り方を解説します。
SP(モバイル)サイズではハンバーガーメニューを、PCではナビゲーションメニューが表示されるようにしていきます。
プログラミング学習でこのような経験はありませんか?
- 目標に向けて何を学べば良いかわからない
- 調べても解決策が見つからない
- 現場レベルのスキルが身につくのか不安
これらの悩みは、学習環境を整えることで全て解決することができます。
ZeroPlus Gateでは、30日間無料で最適な学習環境を提供しています。
- なんでも相談できる専属メンター
- いつでも技術相談ができるプロ講師
- 元IT企業CTO監修のカリキュラム
条件なしでこのレベルの環境を無料で提供しているのはZeroPlus Gateだけです。
ただし、無料サービスの提供には参加者の数に制限があります。
少しでも興味がある方は、以下のリンクからサービスの詳細をご覧ください。
目次
サンプルのダウンロード
以下のリンクからサンプルをダウンロードしましょう。
ファイルを開くと、以下2つのファイルが入っています。
- 「code」→HTML・CSSファイル・画像ファイルが入っているファイル
- 「mock」→モックアップ画像
下記からサンプルコードを確認することもできます。
See the Pen JS ハンバーガーメニュー by ZeroPlus (@zeroplus-programming) on CodePen.
デザインの確認
エディタでファイルを開くと、mockフォルダの中にモックアップ画像ファイルが3つ入っています。全体のデザインを確認しましょう。
SP(モバイル)デザイン(sp-mock.png)
ハンバーガーメニューをクリックしたときにナビゲーションメニューが出るようにしていきます。
PCのデザイン(pc-mock.png)
PCデザインのときはハンバーガーメニューは非表示、ナビゲーションメニューが表示されるようにしていきます。
コーディングしてみよう
コーディングを行う際はいきなりコードを記述せず、サイトのデザインを確認します。
- サイトのデザインを確認する
- HTMLでサイトの構造を記述する
- CSSでサイトの見た目を整えていく
- JavaScriptで動きをつけていく
上記の流れを意識して、実際にコーディングを行っていきます。
全体のレイアウト
HTMLで構造を記述する
まずは大枠を作成します。
<body>
<div class="container">
<header class="header">
</header>
<main>
<div class="main">
メインコンテンツエリア
</div>
</main>
<footer class="footer">
<div>
フッターエリア
</div>
</footer>
</div>
</body>
containerクラスの中にheader、footer、main、を記述します。
CSSでサイトの見た目を整えていく
今回のサイトを制作するにあたってこちらのサイトを参考にreset.cssを作成し、linkタグでreset.cssを適用します。
reset.cssは各ブラウザで適用されているデフォルトスタイルを上書きして、各ブラウザのスタイルを揃える役割があります。
reset.cssはstyle.cssより先に記述しています。
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title> Document </title>
<link rel="stylesheet" href="reset.css">
<link rel="stylesheet" href="style.css">
</head>
ヘッダーとフッター、mainタグ内のスタイルを整える
style.cssにmainタグ、footerタグにスタイルをあてます。
/* 調整用スタイル */
a {
text-decoration: none;
}
ul,
li {
list-style: none;
}
main {
background-color: #f1f1f1;
height: 800px;
display: flex;
}
.main {
margin: auto;
}
.footer {
background-color: #f6f6f6;
height: 200px;
display: flex;
}
.footer div {
margin: auto;
}
aタグはデフォルトでアンダーラインが表示されるので、text-decoration: none;を用いてアンダーラインを非表示にします。
ulタグ、liタグも同様に「・」がデフォルトで文頭に表示されるので、list-style: none;を用いて非表示にします。
続いてヘッダーにスタイルをあてます。
/* ヘッダー */
.header {
background-color: white;
width: 100%;
height: 50px;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
}
スクロールしてもヘッダーを追従させたいので、position: fixed;を適用します。
また、ヘッダーは表示順を上にしたいのでz-index: 999;を指定します。
ヘッダーを作る
HTMLで構造を記述する
headerタグの中を作ります。
<header class="header">
<div class="header__inner">
<h1 class="header__title header-title">
<a href="#">
<img src="images/logo-black.png" alt="ロゴ画像">
</a>
</h1>
<nav class="header__nav nav">
</nav>
<button class="header__hamburger hamburger">
</button>
</div>
</header>
ヘッダーの中の左右の余白を確保するため、header-innerクラスを入れています。h1タグの中にはimgタグでロゴ画像を適用しています。ロゴ画像をクリックしたらトップに戻りたいのでimgタグをaタグで囲います。
ナビゲーションメニュー用にnavタグを記述します。
ハンバーガーメニューはbuttonタグで作成します。buttonタグで作る理由はフォーカスを適用させるためです。divタグで作るとフォーカスが当たりません。
CSSでヘッダーの見た目を整えていく
2022年現在、モバイルファーストで記述することが推奨されているので、SP(モバイル)サイズから適用していきます。
style.cssに以下のように記述します。
.header__inner {
padding: 0 20px; /*左右の余白確保*/
display: flex; /*ロゴとハンバーガーメニューを横に並べる*/
align-items: center;
justify-content: space-between;
height: inherit; /*親要素の高さを継承*/
position: relative;
}
/* ヘッダーのロゴ部分 */
.header__title {
width: 80px;
}
.header__title img {
display: block;
width: 100%;
height: 100%;
}
/* ヘッダーのナビ部分 */
.header__nav {
position: absolute;
right: 0;
left: 0;
top: 0;
width: 100%;
height: 100vh;
transform: translateX(100%);
background-color: #fff; /*ハンバーガーメニュークリック時のナビゲーションメニュー背景色*/
transition: ease .4s; /*ハンバーガーメニュークリック時のナビゲーションメニュー出現を遅延*/
}
/* ハンバーガーメニュー */
.header__hamburger {
width: 48px;
height: 100%;
}
.hamburger {
background-color: transparent; /*buttonタグデフォルトスタイルを打ち消し*/
border-color: transparent; /*buttonタグデフォルトスタイルを打ち消し*/
z-index: 9999;
}
header-innerクラスではロゴの左側とハンバーガーメニューの右側に余白をpaddingで確保しています。
ロゴとハンバーガーメニューを横並びにしたいのでflexboxを利用しています。
header__navクラスはtransform: translateX(100%);でコンテンツよりも右側に移動させておきます。
hamburgerクラスはフォーカスを当てたいのでbuttonタグを使用します。その際にbuttonタグにデフォルトで当たっている一部のスタイルを、別のスタイルで打ち消します。
ハンバーガーメニューを作る
HTMLで構造を記述する
ハンバーガーメニューを作ります。
<button class="header__hamburger hamburger">
<span></span>
<span></span>
<span></span>
</button>
ハンバーガーメニューの三本線を表現するためにspanタグを使用します。
CSSでハンバーガーメニューの見た目を整えていく
/* ハンバーガーメニューの線 */
.hamburger span {
width: 100%;
height: 1px;
background-color: #000;
position: relative;
transition: ease .4s; /*ハンバーガーメニュークリック時の三本線の動きを遅延*/
display: block;
}
.hamburger span:nth-child(1) {
top: 0;
}
.hamburger span:nth-child(2) {
margin: 8px 0;
}
.hamburger span:nth-child(3) {
top: 0;
}
ハンバーガーメニューの三本線をpositionで微調整します。線はwidthとheight、線の色をbackground-colorで表現しています。
ハンバーガーメニュークリック後の動きを作る
HTMLで構造を記述する
<nav class="header__nav nav" id="js-nav">
<ul class="nav__items nav-items">
</ul>
</nav>
<button class="header__hamburger hamburger active" id="js-hamburger">
<span></span>
<span></span>
<span></span>
</button>
ハンバーガーメニューをクリックしたらactiveクラスを付与するようにしていきます。activeクラスが付いた状態のレイアウトを画面で確認しながらスタイルを整えたいので、hamburgerクラスにactiveクラスを併記しておきます。
「ハンバーガーメニューをクリックしたらactiveクラスを付与する」というのを、JavaScriptで制御したいのでidでjs-hamburgerを付けておきます。js-〇〇 というid名は、JavaScript(jQuery含む)で制御するという意味になります。基本的にjs-〇〇はCSSでスタイルを付けません。
navタグもJavaScriptで動きを制御したいのでidを付与します。
CSSでハンバーガーメニューの見た目を整えていく
* ハンバーガーメニュークリック後のスタイル */
.header__nav.active {
transform: translateX(0);
}
.hamburger.active span:nth-child(1) {
top: 5px;
transform: rotate(45deg);
}
.hamburger.active span:nth-child(2) {
opacity: 0;
}
.hamburger.active span:nth-child(3) {
top: -13px;
transform: rotate(-45deg);
}
hamburgerクラスにactiveクラスが付いた状態のスタイルを記述していきます。
アクティブクラスがついたら三本線の真ん中はopacityで透明にします。
他の線はtransform: rotate(○○deg);で回線させ「×」になるように調整します。
ハンバーガーメニュークリック後activeクラスが付いたら、transform: translateX(0);にして元の位置に戻るように設定しておきます。
activeクラスが付いた状態のスタイルを確認したら、HTMLからactiveクラスを削除します。
JavaScriptでハンバーガーメニュークリック時の動きを制御する
ここからJavaScriptを使ってハンバーガーメニューの動きを制御していきます。
main.jsファイルに以下のような記述をします。
const ham = document.querySelector('#js-hamburger'); //js-hamburgerの要素を取得し、変数hamに格納
const nav = document.querySelector('#js-nav'); //js-navの要素を取得し、変数navに格納
ham.addEventListener('click', function () { //ハンバーガーメニューをクリックしたら
console.log('ok!'); // コンソール画面でokというメッセージが出る
});
あらかじめHTMLで付与しておいた要素をdocument.querySeletorで取得し、変数に格納します。
addEventListenerを使ってクリックイベントを登録します。今回はハンバーガーメニューをクリックしたらクリックイベントを発動させたいので、先ほど作成した変数hamを使用していきます。
「ハンバーガーメニューをクリックしたら」クリックイベントが発動するかどうかの確認のため、console.logを使って確認していきます。
コンソール画面で「ok!」のメッセージが表示されればOKです。もしこの時点で表示されなければ、以下の理由が考えられます。
- 要素が取得できていない(スペルミスなど)
- addEventListenerやfunctionなどの記述ミス
- HTML側でidを付けていない(js-〇〇)
- HTML側のid名のスペルミス
- HTML側のid名とdocument.querySeletorで取得するid名が一致していない
「ok!」のメッセージが表示されたらクリックイベントの確認が取れましたので、addEventListenerの中を作っていきます。その際、console.logは不要なので削除します。
ham.addEventListener('click', function () { //ハンバーガーメニューをクリックしたら
ham.classList.toggle('active'); // ハンバーガーメニューにactiveクラスを付け外し
nav.classList.toggle('active'); // ナビゲーションメニューにactiveクラスを付け外し
});
classListは特定の要素のクラス名を追加・削除・参照したりすることが出来るプロパティです! classListは下記のようなメソッドを持っています。
- add:要素にクラスを追加
- remove:要素からクラスを削除
- toggle:要素が持っている特定のクラスを切り替え
- contains:クラスを持っているか確認
今回はクリックしたらactiveクラスの付け外しをしていきたいので、classList.toggleを使用しています。
この状態でクリックするとハンバーガーメニューの三本線が「×」に代わるようになります。そしてナビゲーションの白背景(header__navクラス)が右側から出現します。
ナビゲーションメニューを作る
HTMLで構造を記述する
ナビゲーションメニューを作ります。
<nav class="header__nav nav" id="js-nav">
<ul class="nav__items nav-items">
<li class="nav-items__item"><a href="">メニュー</a></li>
<li class="nav-items__item"><a href="">メニュー</a></li>
<li class="nav-items__item"><a href="">メニュー</a></li>
<li class="nav-items__item"><a href="">メニュー</a></li>
</ul>
</nav>
ナビゲーションメニューはulタグ、liタグで作っていきます。メニューをクリックしたらリンク先に遷移するようにaタグも記述します。
CSSでナビゲーションメニューのスタイルを整える
.nav-items {
padding-top: 250px;
padding-bottom: 200px;
}
/* ナビのリンク */
.nav-items__item a {
color: black;
width: 100%;
display: block;
text-align: center;
font-size: 20px;
margin-bottom: 24px;
}
.nav-items__item:last-child a {
margin-bottom: 0;
}
メニュー間の余白を調整するため、margin-bottomで余白を設けます。最後のメニューに関しては、下余白は不要なのでlast-childでmargin-bottomを0にして余白を打ち消します。
これでSP(モバイル)サイズは完成しました。次にレスポンシブ対応するためにPCサイズを作ります!
レスポンシブでPCサイズを作る
レスポンシブではメディアクエリを使用します。
モバイルファーストかPCファーストかで書き方が異なります。
- @medeia screen and (min-width: ○○px) { }・・・モバイルファースト
- @medeia screen and (max-width: ○○px) { }・・・PCファースト
今回は960pxからPCサイズに設定したいので、@medeia screen and (min-width: 960px) とします。
CSSでPCサイズのスタイルを整える
書き方はいろいろありますが、ここではSP時のスタイルの直下にPC時のスタイルを記述する形にします。ブロックごとに分けることで、あとでスタイルが変更になった場合でも修正しやすくなります。
なお@media screen and (min-width: 960px)の中でまとめて適用しても大丈夫です。
/* ヘッダーのロゴ部分 */
.header__title {
width: 80px;
}
@media screen and (min-width: 960px) {
.header__title {
width: 120px;
}
}
/* ヘッダーのナビ部分 */
.header__nav {
position: absolute;
right: 0;
left: 0;
top: 0;
width: 100%;
height: 100vh;
transform: translateX(100%);
background-color: #fff;
transition: ease .4s;
}
@media screen and (min-width: 960px) {
.header__nav {
position: static;
transform: initial;
background-color: inherit;
height: inherit;
display: flex;
justify-content: end;
width: 50%;
}
}
/*PC時のナビゲーションメニュー、横並びにする*/
@media screen and (min-width: 960px) {
.nav__items {
width: 100%;
display: flex;
align-items: center;
height: initial;
justify-content: space-between;
}
}
.nav-items {
padding-top: 250px;
padding-bottom: 200px;
}
@media screen and (min-width: 960px) {
.nav-items {
padding-top: inherit;
padding-bottom: inherit;
}
}
/* ナビのリンク */
.nav-items__item a {
color: black;
width: 100%;
display: block;
text-align: center;
font-size: 20px;
margin-bottom: 24px;
}
@media screen and (min-width: 960px) {
.nav-items__item a {
margin-bottom: 0;
}
}
/*ハンバーガーメニュー*/
.hamburger {
background-color: transparent;
border-color: transparent;
z-index: 9999;
}
@media screen and (min-width: 960px) {
/*PC時非表示にする*/
.hamburger {
display: none;
}
}
ハンバーガーメニューはPC時非表示にしたいのでdisplay: none;を適用します。
ナビゲーションメニューはSP時縦並びになっていましたが、PC時では横並びに変更したいのでflexboxを適用していきます。
まとめ
この記事で紹介したハンバーガーメニューの作り方は一つの例にすぎません。他にもさまざまな作り方があります。
プログラミング学習でこのような経験はありませんか?
- 目標に向けて何を学べば良いかわからない
- 調べても解決策が見つからない
- 現場レベルのスキルが身につくのか不安
これらの悩みは、学習環境を整えることで全て解決することができます。
ZeroPlus Gateでは、30日間無料で最適な学習環境を提供しています。
- なんでも相談できる専属メンター
- いつでも技術相談ができるプロ講師
- 元IT企業CTO監修のカリキュラム
条件なしでこのレベルの環境を無料で提供しているのはZeroPlus Gateだけです。
ただし、無料サービスの提供には参加者の数に制限があります。
少しでも興味がある方は、以下のリンクからサービスの詳細をご覧ください。