本記事では、ホームページなどでよく見かける画面右(左)上の三本線アイコン(ハンバーガーメニュー)の実装方法(HTML/CSS/JavaScriptコード)を、実装例とともに紹介します。
右上の三本線アイコンをクリックすると、中央にフワッとメニューが表示されます。
自分の学習・メモ用がメインですが、プログラミング学習初心者の参考になればとも思います!
ハンバーガーメニューの実装手順
以下の3ステップで、実装方法を解説&コードを公開しています。
- ハンバーガーメニューのアイコン作成
- アイコンをクリックしてメニューを表示
- 画面幅に合わせて表示を変える
ハンバーガーメニューのアイコンを作る
まずはアイコンの作り方です。(メニュー表示は次項)
三本線アイコンをクリック(タップ)すると、「✖」マークに変化します。
「✖」マークをクリック(タップ)すると、再び三本線アイコンに戻ります。
HTML / CSS / JavaScript コード
<div class="hamburger-menu">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
.hamburger-menu {
width: 30px;
height: 22px;
position: absolute;
top: 20px;
right: 20px;
cursor: pointer;
}
.line {
background-color: black;
height: 4px;
width: 100%;
position: absolute;
transition: all 0.3s;
}
.line:nth-of-type(1) {
top: 0;
}
.line:nth-of-type(2) {
top: 50%;
transform: translateY(-50%);
}
.line:nth-of-type(3) {
bottom: 0;
}
.hamburger-menu.active > .line:nth-of-type(1) {
top: 50%;
transform: translateY(-50%) rotate(45deg);
}
.hamburger-menu.active > .line:nth-of-type(2) {
display: none;
}
.hamburger-menu.active > .line:nth-of-type(3) {
top: 50%;
transform: translateY(-50%) rotate(-45deg);
}
const hamburgerMenu = document.querySelector('.hamburger-menu');
hamburgerMenu.addEventListener('click', () => {
hamburgerMenu.classList.toggle('active');
});
三本線アイコンの作り方
本実装例の三本線アイコンは、以下のHTMLとCSSで表現しています。
<div class="hamburger-menu">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
.line {
background-color: black;
height: 4px;
width: 100%;
position: absolute;
}
.line:nth-of-type(1) {
top: 0;
}
.line:nth-of-type(2) {
top: 50%;
transform: translateY(-50%);
}
.line:nth-of-type(3) {
bottom: 0;
}
position
プロパティを使うことで、親要素(hamburger-menuクラスが付いたdiv要素)に対し、子要素(各ライン)を指定の位置に配置できます。
- ライン1つ目
-
top: 0;
→ 親要素の上端に配置 - ライン2つ目
-
top: 50%;
&transform: translateY(-50%);
→ 親要素の中央に配置 - ライン3つ目
-
bottom: 0;
→ 親要素の下端に配置
クリック時のアニメーション
まずアイコンをクリックすることで、アイコン要素にactiveクラスを付け外しできるJavaScriptを実装します。
hamburgerMenu.addEventListener('click', () => {
hamburgerMenu.classList.toggle('active');
});
次にCSSで、アイコン要素にactiveクラスが付いたときのスタイルを適用します。
.hamburger-menu.active > .line:nth-of-type(1) {
top: 50%;
transform: translateY(-50%) rotate(45deg);
}
.hamburger-menu.active > .line:nth-of-type(2) {
display: none;
}
.hamburger-menu.active > .line:nth-of-type(3) {
top: 50%;
transform: translateY(-50%) rotate(-45deg);
}
真ん中のラインはdisplay: none;
で非表示にします。
上端と下端のラインは、top: 50%;
&transform: translateY(-50%);
で真ん中に配置し、rotate(45deg)
&rotate(-45deg)
で逆方向に回転させると、「✖」アイコンが作れます。
また、アニメーションに動きを付けるため、transition
プロパティを合わせて適用しています。
.line {
transition: all 0.3s;
}
このプロパティにより、0.3秒かけて前述のスタイルが適用されるようになります。
アイコンをクリックしてメニューを表示させる
次に、アイコンをクリックすることで画面中央にメニューをフワッと表示させる方法です。
再度「✖」アイコンをクリックするとメニューが閉じます。
HTML / CSS / JavaScript コード
<div class="hamburger-menu">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
<nav class="nav-menu">
<a href="#">メニュー1</a>
<a href="#">メニュー2</a>
<a href="#">メニュー3</a>
</nav>
.hamburger-menu {
width: 30px;
height: 22px;
position: absolute;
top: 20px;
right: 20px;
cursor: pointer;
}
.line {
background-color: black;
height: 4px;
width: 100%;
position: absolute;
transition: all 0.3s;
}
.line:nth-of-type(1) {
top: 0;
}
.line:nth-of-type(2) {
top: 50%;
transform: translateY(-50%);
}
.line:nth-of-type(3) {
bottom: 0;
}
.hamburger-menu.active > .line:nth-of-type(1) {
top: 50%;
transform: translateY(-50%) rotate(45deg);
}
.hamburger-menu.active > .line:nth-of-type(2) {
display: none;
}
.hamburger-menu.active > .line:nth-of-type(3) {
top: 50%;
transform: translateY(-50%) rotate(-45deg);
}
.nav-menu {
display: none;
flex-direction: column;
position: absolute;
top: 45%;
left: 50%;
transform: translate(-50%, -50%);
align-items: center;
justify-content: center;
padding: 8px;
width: 200px;
background-color: #fff;
border: 1px solid #ccc;
opacity: 0;
}
.nav-menu.active {
display: flex;
animation: fadeIn 0.5s forwards;
}
.nav-menu a {
text-decoration: none;
color: black;
padding: 5px;
margin: 5px;
}
@keyframes fadeIn {
0% {
top: 45%;
opacity: 0;
}
100% {
top: 50%;
opacity: 1;
}
}
const hamburgerMenu = document.querySelector('.hamburger-menu');
const navMenu = document.querySelector('.nav-menu');
hamburgerMenu.addEventListener('click', () => {
hamburgerMenu.classList.toggle('active');
navMenu.classList.toggle('active');
});
メニューの作り方
本実装例のメニューは、以下のHTMLとCSSで表現しています。
<nav class="nav-menu">
<a href="#">メニュー1</a>
<a href="#">メニュー2</a>
<a href="#">メニュー3</a>
</nav>
.nav-menu {
display: none;
flex-direction: column;
position: absolute;
top: 45%;
left: 50%;
transform: translate(-50%, -50%);
align-items: center;
justify-content: center;
padding: 8px;
width: 200px;
background-color: #fff;
border: 1px solid #ccc;
opacity: 0;
}
.nav-menu.active {
display: flex;
animation: fadeIn 0.5s forwards;
}
.nav-menu a {
text-decoration: none;
color: black;
padding: 5px;
margin: 5px;
}
メニューの配置は、アイコンと同じくposition
プロパティを使って、画面中央にくるよう配置しています。
後述のアニメーションの関係で、top: 45%;
と若干上側に配置しています。
また、アイコンクリック前は表示させたくないので、display: none;
で非表示にし、activeクラスが付いたときにdisplay: flex;
で表示させています。opacity: 0;
にしているのは後述のアニメーションの関係です。
フワッと表示させる方法
アイコンをクリック時、メニューを少し上から下に向かってフワッと表示させるには、CSSのkeyframes
プロパティを使います。
まずJavaScriptで、アイコンクリック時にメニュー要素にもactiveクラスを付け外しできるよう実装します。
hamburgerMenu.addEventListener('click', () => {
hamburgerMenu.classList.toggle('active');
navMenu.classList.toggle('active');
});
次にCSSで、メニュー要素にactiveクラスが付いたときのスタイルを適用します。
.nav-menu.active {
display: flex;
animation: fadeIn 0.5s forwards;
}
display: flex;
でメニューが表示され、fadeInというanimation
が0.5秒かけて行われ、アニメーション終了後の形でとどまります。
fadeInアニメーションは以下の通り設定しています。
@keyframes fadeIn {
0% {
top: 45%;
opacity: 0;
}
100% {
top: 50%;
opacity: 1;
}
}
これにより、0.5秒かけてメニューの位置が5%下がり(top: 45%;
→top: 50%;
)、
フワッと表示(opacity: 0;
→opacity: 1;
)されるようになります。
デバイス(PC/スマホ)に応じて表示を変える
以上でハンバーガーメニューは完成ですが、基本的にハンバーガーメニューは画面幅が小さいモバイルなどで適用され、PCなど広い画面幅では使われません。(わざわざ三本線アイコンにせず、ヘッダーなどにメニューをそのまま表示させます。)
そこで最後に、画面幅に応じて表示を変える実装方法を紹介します。
画面幅を800px以下にすると、ハンバーガーメニューが表示されます。
HTML / CSS / JavaScript コード
<div class="container">
<div class="header">
<div class="logo">仮ロゴ</div>
<nav class="pc-menu">
<ul>
<li><a href="#">メニュー1</a></li>
<li><a href="#">メニュー2</a></li>
<li><a href="#">メニュー3</a></li>
</ul>
</nav>
<div class="mobile-menu hamburger-menu">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
</div>
<nav class="nav-menu">
<a href="#" class="menu-link">メニュー1</a>
<a href="#" class="menu-link">メニュー2</a>
<a href="#" class="menu-link">メニュー3</a>
</nav>
</div>
/* ==== ヘッダーのスタイル ==== */
.header {
width: 100%;
height: 80px;
background: rgba(0, 0, 0, .2);
display: flex;
justify-content: space-between;
}
.header .logo {
width: 20%;
height: 80px;
text-align: center;
line-height: 80px;
font-size: 20px;
font-weight: 600;
background: skyblue;
}
.header nav {
width: 50%;
}
.header ul {
width: 100%;
display: flex;
list-style: none;
padding: 0;
margin: 0;
}
.header ul li {
width: 33%;
}
.header a {
display: block;
width: 100%;
line-height: 80px;
text-align: center;
text-decoration: none;
color: black;
}
/* ==== ハンバーガーメニューのスタイル ==== */
.hamburger-menu {
display: none;
width: 30px;
height: 22px;
position: relative;
top: 50%;
right: 20px;
transform: translateY(-50%);
cursor: pointer;
}
.line {
background-color: black;
height: 4px;
width: 100%;
position: absolute;
transition: all 0.3s;
}
.line:nth-of-type(1) {
top: 0;
}
.line:nth-of-type(2) {
top: 50%;
transform: translateY(-50%);
}
.line:nth-of-type(3) {
bottom: 0;
}
.hamburger-menu.active > .line:nth-of-type(1) {
top: 50%;
transform: translateY(-50%) rotate(45deg);
}
.hamburger-menu.active > .line:nth-of-type(2) {
display: none;
}
.hamburger-menu.active > .line:nth-of-type(3) {
top: 50%;
transform: translateY(-50%) rotate(-45deg);
}
.nav-menu {
display: none;
flex-direction: column;
position: absolute;
top: 45%;
left: 50%;
transform: translate(-50%, -50%);
align-items: center;
justify-content: center;
padding: 8px;
width: 200px;
background-color: #fff;
border: 1px solid #ccc;
opacity: 0;
}
.nav-menu.active {
display: flex;
animation: fadeIn 0.5s forwards;
}
.nav-menu a {
text-decoration: none;
color: black;
padding: 5px;
margin: 5px;
}
@keyframes fadeIn {
0% {
top: 45%;
opacity: 0;
}
100% {
top: 50%;
opacity: 1;
}
}
@media (max-width: 800px) {
.hamburger-menu {
display: block;
}
.pc-menu {
display: none;
}
}
const hamburgerMenu = document.querySelector('.hamburger-menu');
const navMenu = document.querySelector('.nav-menu');
hamburgerMenu.addEventListener('click', () => {
hamburgerMenu.classList.toggle('active');
navMenu.classList.toggle('active');
});
固定表示ヘッダーの作り方
以下記事で詳しく紹介しています。
画面幅に応じて表示を変える方法(レスポンシブウェブデザイン)
メディアクエリと呼ばれるCSSの記法を使って実装します。
@media (max-width: 800px) {
.hamburger-menu {
display: block;
}
.pc-menu {
display: none;
}
}
これにより、画面幅が800px以下の場合にハンバーガーメニューが表示され、800pxを超えるとヘッダーにそのままメニューが表示されるようになります。
詳細は、以下記事で詳しく紹介しています。
まとめ
以上、ハンバーガーメニューの実装方法について紹介しました。
ウェブデザインの参考になれば嬉しいです。
当サイトで公開しているWebデザインやUIの実装例は、一覧として以下記事に纏めています。