モダンなウェブデザインに欠かせないハンバーガーメニューは、スマートフォンやタブレットの普及により、今やほとんどのウェブサイトで見かける定番の要素となっています。
この記事では、ハンバーガーメニューの基本から実践的な実装方法まで、初心者にもわかりやすく解説します。
詳しく解説していますので、コードだけほしい方はこちらから
見本
今回は下記のようなハンバーガーメニューを作っていきます。
See the Pen ハンバーガーメニュー by ryoma (@hwjgdjpk-the-decoder) on CodePen.
ポイントは下記になります。
- 3本線をクリックすると✕印になり、色は白くなる
- 3本線をクリックするとドロワーメニューが出てくる
- ドロワーメニューのリンクをクリックすると閉じる
- ドロワーメニューのメニュー以外をクリックしても閉じる
- ドロワーメニューのリンクがページ内リンクでも閉じる
ハンバーガーメニューの見た目の制作
HTML
<!-- ハンバーガーメニュー -->
<div class="hamburger js-hamburger sp-show">
<span></span>
<span></span>
<span></span>
</div>
<!-- ドロワーメニュー -->
<div class="drawer js-drawer">
<div class="drawer-inner">
<div class="drawer__nav">
<ul class="drawer__list">
<li class="drawer__item">
<a href="#" class="drawer__link">Home</a>
</li>
<li class="drawer__item">
<a href="#about" class="drawer__link">About</a>
</li>
<li class="drawer__item">
<a href="#works" class="drawer__link">Works</a>
</li>
<li class="drawer__item">
<a href="#service" class="drawer__link">Service</a>
</li>
</ul>
</div>
</div>
</div>
まずはHTMLですが、
大きく分けて以下の2つの構造になっています。
- ハンバーガー(3本線の部分)
- ドロワーメニュー(クリックすると出てくるメニュー)
ハンバーガーメニューの部分
<div class="hamburger js-hamburger sp-show">
<span></span>
<span></span>
<span></span>
</div>
hamburger
: このクラスは、ハンバーガーメニューアイコン(3本の横線)のスタイリングに使用されます。js-hamburger
: JavaScriptでイベントリスナー(クリックイベントなど)を追加する際に使用するクラスです。これにより、メニューの開閉を制御できます。sp-show
: これは「スマートフォン表示時のみ表示(show)」を意味するクラスです。レスポンシブデザインにおいて、特定の画面サイズでのみこの要素を表示するために使用されます。<span></span>
: これら3つの<span>
タグは、ハンバーガーメニューの各線を表しています。CSSを使用してこれらにスタイリングを適用することで、ユーザーに視覚的に認識されるアイコンが形成されます。
ドロワーメニューの部分
<div class="drawer js-drawer">
<div class="drawer-inner">
<div class="drawer__nav">
<ul class="drawer__list">
<li class="drawer__item">
<a href="#" class="drawer__link">Home</a>
</li>
<li class="drawer__item">
<a href="#about" class="drawer__link">About</a>
</li>
<li class="drawer__item">
<a href="#works" class="drawer__link">Works</a>
</li>
<li class="drawer__item">
<a href="#service" class="drawer__link">Service</a>
</li>
</ul>
</div>
</div>
</div
drawer
: このクラスは、ドロワーメニュー(ハンバーガーメニューをクリックすると出現するナビゲーションメニュー)のスタイリングに使用されます。js-drawer
: こちらもJavaScriptの操作対象となるクラスです。メニューの開閉などの動作を制御するために使用されるためのクラスです。drawer-inner
は外側のコンテナを、drawer__nav
はナビゲーション部分をそれぞれ表しています。<ul class="drawer__list">
: メニュー項目のリストを表します。この中に、ナビゲーションリンクを含むリストアイテムが配置されます。<li class="drawer__item">
と<a href="#" class="drawer__link">
: これらはそれぞれナビゲーションリンクを含むリストアイテムです。
CSS
/*=========================================
#hamburger
=========================================*/
.hamburger {
position: fixed;
top: 20px;
right: 20px;
z-index: 150;
width: 30px;
height: 30px;
cursor: pointer;
}
.hamburger.is-active span:nth-child(1) {
top: 50%;
transform: translate(-50%, -50%) rotate(135deg);
}
.hamburger.is-active span:nth-child(2) {
opacity: 0;
}
.hamburger.is-active span:nth-child(3) {
top: 50%;
transform: translate(-50%, -50%) rotate(-135deg);
}
.hamburger span {
position: absolute;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
height: 2px;
background-color: #333333;
transition: transform .3s;
}
.hamburger.is-active span {
background-color: #ffffff;
}
.hamburger span:nth-child(1) {
top: 30%;
}
.hamburger span:nth-child(2) {
top: 60%;
}
.hamburger span:nth-child(3) {
top: 90%;
}
/*=========================================
#drawer
=========================================*/
.drawer {
visibility: hidden;
opacity: 0;
position: fixed;
top: 0;
left: 0;
z-index: 130;
width: 100%;
height: 100vh;
background-color: #333333;
transition: opacity .3s, visibility .3s;
}
.drawer.is-active {
visibility: visible;
opacity: 1;
}
.drawer-inner {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
padding: 0 20px;
}
.drawer__list {
display: flex;
flex-direction: column;
gap: 50px;
}
.drawer__link {
color: #ffffff;
}
/* ===============================================
# 共通
=============================================== */
a {
color: inherit;
text-decoration: none;
}
img {
max-width: 100%;
height: auto;
background-size: cover;
background-repeat: no-repeat;
font-style: italic;
vertical-align: middle;
shape-margin: .75rem;
}
/* 実際のプロジェクトではここのコメントを解除して、スマホ時のみ表示させます。 */
/* .sp-show {
display: none;
}
@media screen and (max-width: 768px) {
.sp-show {
display: block;
}
.sp-none {
display: none;
}
} */
主要なポイントを以下に解説します。
ハンバーガーメニューに関するスタイル
.hamburger {
position: fixed;
top: 20px;
right: 20px;
z-index: 150;
width: 30px;
height: 30px;
cursor: pointer;
}
.hamburger
クラスは、ハンバーガーメニューのアイコンの位置やサイズを定義します。position: fixed;
により、アイコンは画面上の固定位置に表示されます。top
とright
で画面の上部と右側からの距離を設定します。z-index
は他の要素より前面に表示させるための値です。cursor: pointer;
はカーソルがアイコンの上にあるときにポインター(手の形)に変わることを示します。
.hamburger.is-active span:nth-child(1) {
top: 50%;
transform: translate(-50%, -50%) rotate(135deg);
}
.hamburger.is-active span:nth-child(2) {
opacity: 0;
}
.hamburger.is-active span:nth-child(3) {
top: 50%;
transform: translate(-50%, -50%) rotate(-135deg);
}
.hamburger.is-active
は、メニューがアクティブ(開かれた)状態のスタイリングを定義します。- 1つ目と3つ目の
span
は、45度の角度で交差するように回転します(クローズアイコンの形になります)。 - 2つ目の
span
は透明になり、見えなくなります。
.hamburger span {
position: absolute;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
height: 2px;
background-color: #333333;
transition: transform .3s;
}
span
要素には、ハンバーガーメニューの各線のスタイルが定義されています。
ドロワーメニューに関するスタイル
.drawer {
visibility: hidden;
opacity: 0;
position: fixed;
top: 0;
left: 0;
z-index: 130;
width: 100%;
height: 100vh;
background-color: #333333;
transition: opacity .3s, visibility .3s;
}
.drawer.is-active {
visibility: visible;
opacity: 1;
}
.drawer
は、ドロワーメニューの基本的なスタイルを定義します。visibility: hidden;
とopacity: 0;
で初期状態ではメニューが見えないように設定されています。.is-active
が追加されると、メニューが表示されます(visibility: visible;
とopacity: 1;
)。
.drawer-inner {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
padding: 0 20px;
}
.drawer__list {
display: flex;
flex-direction: column;
gap: 50px;
}
.drawer__link {
color: #ffffff;
}
- これらのクラスは、ドロワーメニュー内部のレイアウトとスタイルを制御します。
共通
共通以下のCSSは毎回設定するもので、今回はコメントアウト部分がありますが、今回は説明用にPCでも表示できる用にしているので、コメントアウトがあります。
実際に使用するときはPCで表示する必要はないので、下記部分のコメントアウトは外して使ってください。
/* .sp-show {
display: none;
}
@media screen and (max-width: 768px) {
.sp-show {
display: block;
}
.sp-none {
display: none;
}
} */
以上がCSSになります。
ハンバーガーメニューの動きの制作
見た目が完成してので、次は動きをつけてメニューの開閉ができるようにしていきます。
ポイントをおさらいすると以下のようになります。
- 3本線をクリックすると✕印になり、色は白くなる
- 3本線をクリックするとドロワーメニューが出てくる
- ドロワーメニューのリンクをクリックすると閉じる
- ドロワーメニューのメニュー以外をクリックしても閉じる
- ドロワーメニューのリンクがページ内リンクでも閉じる
JavaScriptの完成コード
/*=========================================
#ハンバーガーメニュー
=========================================*/
const hamburger = document.querySelector(".js-hamburger");
const drawer = document.querySelector(".js-drawer");
const drawerLinks = document.querySelectorAll(".js-drawer a");
hamburger.addEventListener('click', () => {
hamburger.classList.toggle('is-active');
drawer.classList.toggle('is-active');
});
drawerLinks.forEach(drawerLink => {
drawerLink.addEventListener('click', () => {
hamburger.classList.remove('is-active');
drawer.classList.remove('is-active');
});
});
drawer.addEventListener('click', () => {
hamburger.classList.remove('is-active');
drawer.classList.remove('is-active');
});
上記コードは、ハンバーガーメニューとドロワーメニューの動的な挙動を制御するためのものです。
主要な部分を解説します。
ハンバーガーメニューの動作制御
const hamburger = document.querySelector(".js-hamburger");
const drawer = document.querySelector(".js-drawer");
- ここでは、ハンバーガーメニューのアイコン(
.js-hamburger
)とドロワーメニュー(.js-drawer
)をそれぞれ変数に格納しています。これにより、後続のコードでこれらの要素を操作できるようになります。
hamburger.addEventListener('click', () => {
hamburger.classList.toggle('is-active');
drawer.classList.toggle('is-active');
});
- ハンバーガーメニューのアイコンにクリックイベントリスナーを追加しています。
- ユーザーがアイコンをクリックすると、
.is-active
クラスが追加されたり削除されたりします。このクラスの追加/削除により、CSSで定義されたスタイルが適用され、メニューの開閉が実現されます。
ドロワーメニューのリンクに対する動作
const drawerLinks = document.querySelectorAll(".js-drawer a");
drawerLinks.forEach(drawerLink => {
drawerLink.addEventListener('click', () => {
hamburger.classList.remove('is-active');
drawer.classList.remove('is-active');
});
});
- ドロワーメニュー内の各リンクに対して、クリックイベントリスナーを追加しています。
- ユーザーがどれかのリンクをクリックすると、ハンバーガーメニューとドロワーメニューの両方から
.is-active
クラスが削除され、メニューが閉じます。
ドロワーメニュー自体に対する動作
drawer.addEventListener('click', () => {
hamburger.classList.remove('is-active');
drawer.classList.remove('is-active');
});
- ドロワーメニュー全体にもクリックイベントリスナーを追加しています。
- ユーザーがドロワーメニューの外側(つまりメニュー自体)をクリックすると、同様に
.is-active
クラスが削除され、メニューが閉じます。
このJavaScriptコードは、ハンバーガーメニューの開閉や、ドロワーメニュー内のリンクをクリックした際の動作をスムーズに制御するためのものです。ユーザーの操作に対して直感的で応答性の高いインタラクションを提供することが目的です。
完成コード
以下は完成後のコードです。
HTML
<!-- ハンバーガーメニュー -->
<div class="hamburger js-hamburger sp-show">
<span></span>
<span></span>
<span></span>
</div>
<!-- ドロワーメニュー -->
<div class="drawer js-drawer">
<div class="drawer-inner">
<div class="drawer__nav">
<ul class="drawer__list">
<li class="drawer__item">
<a href="#" class="drawer__link">Home</a>
</li>
<li class="drawer__item">
<a href="#about" class="drawer__link">About</a>
</li>
<li class="drawer__item">
<a href="#works" class="drawer__link">Works</a>
</li>
<li class="drawer__item">
<a href="#service" class="drawer__link">Service</a>
</li>
</ul>
</div>
</div>
</div>
CSS
/*=========================================
#hamburger
=========================================*/
.hamburger {
position: fixed;
top: 20px;
right: 20px;
z-index: 150;
width: 30px;
height: 30px;
cursor: pointer;
}
.hamburger.is-active span:nth-child(1) {
top: 50%;
transform: translate(-50%, -50%) rotate(135deg);
}
.hamburger.is-active span:nth-child(2) {
opacity: 0;
}
.hamburger.is-active span:nth-child(3) {
top: 50%;
transform: translate(-50%, -50%) rotate(-135deg);
}
.hamburger span {
position: absolute;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
height: 2px;
background-color: #333333;
transition: transform .3s;
}
.hamburger.is-active span {
background-color: #ffffff;
}
.hamburger span:nth-child(1) {
top: 30%;
}
.hamburger span:nth-child(2) {
top: 60%;
}
.hamburger span:nth-child(3) {
top: 90%;
}
/*=========================================
#drawer
=========================================*/
.drawer {
visibility: hidden;
opacity: 0;
position: fixed;
top: 0;
left: 0;
z-index: 130;
width: 100%;
height: 100vh;
background-color: #333333;
transition: opacity .3s, visibility .3s;
}
.drawer.is-active {
visibility: visible;
opacity: 1;
}
.drawer-inner {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
padding: 0 20px;
}
.drawer__list {
display: flex;
flex-direction: column;
gap: 50px;
}
.drawer__link {
color: #ffffff;
}
/* ===============================================
# 共通
=============================================== */
a {
color: inherit;
text-decoration: none;
}
img {
max-width: 100%;
height: auto;
background-size: cover;
background-repeat: no-repeat;
font-style: italic;
vertical-align: middle;
shape-margin: .75rem;
}
.sp-show {
display: none;
}
@media screen and (max-width: 768px) {
.sp-show {
display: block;
}
.sp-none {
display: none;
}
}
JavaScript
/*=========================================
#ハンバーガーメニュー
=========================================*/
const hamburger = document.querySelector(".js-hamburger");
const drawer = document.querySelector(".js-drawer");
const drawerLinks = document.querySelectorAll(".js-drawer a");
hamburger.addEventListener('click', () => {
hamburger.classList.toggle('is-active');
drawer.classList.toggle('is-active');
});
drawerLinks.forEach(drawerLink => {
drawerLink.addEventListener('click', () => {
hamburger.classList.remove('is-active');
drawer.classList.remove('is-active');
});
});
drawer.addEventListener('click', () => {
hamburger.classList.remove('is-active');
drawer.classList.remove('is-active');
});
まとめ
今回は簡単にハンバーガーメニューを作る方法を詳しく解説しました。
ハンバーガーメニューは使う機会も非常に多いので是非この記事をブックマークして、すぐに見返すことができるようにしておくと便利です。
また、このブログでは他にもコーディングに関する記事を投稿していますので、あわせて参考にしてみてください。
コメント