目次
はじめに
今回は下記のようなハンバーガーメニューを作成しました。ソースコードとともにご紹介します。まずはレイアウトを確認していただければと思います。
ボタン・・・3本線からバツ印に変わるボタン
メニュー・・・右からスライド、第2階層ありのメニュー
メニュー・・・右からスライド、第2階層ありのメニュー
ハンバーガメニューのレイアウト
下記の3本線のボタンをクリックするとハンガーガーメニューが開きます。レイアウトの都合上、ハンバーガーメニューのボタンがヘッダーの両端ではなく本文内にあるので違和感を覚えるかもしれませんが問題なく動作します。
ハンバーガーメニューのソースコード例
PR
ハンバーガーメニューのHTML
<div class="openbtn">
<span></span>
<span></span>
<span></span>
</div>
<nav class="gNav">
<p class="siteTitle">
<a class="siteTitle__link" href="#">
<!-- サイトタイトルやロゴを入れてください。 -->
</a>
</p>
<ul class="gNav__list">
<li class="gNav__item">
<a href="#">メニュー1</a>
</li>
<li class="gNav__item">
<a href="#">メニュー2</a>
</li>
<li class="gNav__item">
<a href="#">メニュー3</a>
</li>
<li class="gNav__item has-child">
<p>
メニュー4
<span class="triangle-up"></span>
<span class="triangle-down"></span>
</p>
<ul class="gNav__list level02">
<li class="gNav__item">
<a href="#">メニュー4-1</a>
</li>
<li class="gNav__item">
<a href="#">メニュー4-2</a>
</li>
<li class="gNav__item">
<a href="#">メニュー4-3</a>
</li>
<li class="gNav__item">
<a href="#">メニュー4-4</a>
</li>
</ul>
</li>
<li class="gNav__item">
<a href="#">メニュー5</a>
</li>
<li class="gNav__item has-child">
<p>
メニュー6
<span class="triangle-up"></span>
<span class="triangle-down"></span>
</p>
<ul class="gNav__list level02">
<li class="gNav__item">
<a href="#">メニュー6-1</a>
</li>
<li class="gNav__item">
<a href="#">メニュー6-2</a>
</li>
<li class="gNav__item">
<a href="#">メニュー6-3</a>
</li>
</ul>
</li>
<li class="gNav__item">
<a href="#">メニュー7</a>
</li>
<li class="gNav__item">
<a href="#">メニュー8</a>
</li>
<li class="gNav__item">
<a href="#">メニュー9</a>
</li>
</ul>
</nav>
ハンバーガーメニューのCSS
.openbtn {
position: fixed;
top: 0;
right: 0;
width: 55px;
height: 55px;
cursor: pointer;
z-index: 10000;
}
.openbtn span {
width: 50%;
position: absolute;
left: 14px;
height: 3px;
border-radius: 2px;
background-color: #191919;
transition: all 0.3s;
}
.openbtn span:nth-of-type(1) {
top: 15px;
}
.openbtn span:nth-of-type(2) {
top: 25px;
}
.openbtn span:nth-of-type(3) {
top: 35px;
}
.openbtn.active span:nth-of-type(1),
.openbtn.active span:nth-of-type(3) {
left: 18px;
width: 30%;
}
.openbtn.active span:nth-of-type(1) {
top: 18px;
transform: translateY(6px) rotate(-45deg);
}
.openbtn.active span:nth-of-type(3){
top: 30px;
transform: translateY(-6px) rotate(45deg);
}
.openbtn.active span:nth-of-type(2) {
opacity: 0;
}
.gNav {
position: fixed;
z-index: 9999;
top: 0;
right: 0;
width: 300px;
max-width: 70%;
height: 100%;
padding-bottom: 40px;
overflow-x: hidden;
overflow-y: scroll;
text-align: center;
background-color: #fdfae1;
transition: all 0.6s;
transform: translateX(300px);
}
.gNav.active {
transform: translateX(0);
}
.gNav .siteTitle {
line-height: 70px;
}
.gNav__list a,
.gNav__list p {
padding: 10px;
border-bottom: 1px solid currentColor;
}
.gNav__list a {
display: block;
}
.gNav__list p {
position: relative;
}
.has-child .triangle-down,
.has-child.open .triangle-up {
display: none;
}
.has-child.open .triangle-down {
display: block;
}
.triangle-up::before,
.triangle-down::before {
content: "";
position: absolute;
top: 50%;
right: 10px;
}
.triangle-up::before {
border-bottom: 8px solid currentColor;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
transform: translate(-50%,-65%);
}
.triangle-down::before {
border-top: 8px solid currentColor;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
transform: translate(-50%,-35%);
}
.level02 {
height: 0;
opacity: 0;
visibility: hidden;
transition: all 0.3s;
}
.has-child.open .level02 {
opacity: 1;
visibility: visible;
}
ハンバーガーメニューのJavaScript
純粋なJavaScriptの場合
const openBtn = document.querySelector(".openbtn");
const gNav = document.querySelector(".gNav");
const hasChilds = document.querySelectorAll(".has-child");
const level02 = document.querySelectorAll(".level02");
openBtn.addEventListener("click", function() {
this.classList.toggle("active");
gNav.classList.toggle("active");
});
hasChilds.forEach(function(element) {
element.addEventListener("click", function() {
this.classList.toggle("open");
if (this.classList.contains('open')) {
const ulChild = this.querySelector('ul');
const liElements = ulChild.querySelectorAll('li');
const liHeight = liElements.length > 0 ? liElements[0].offsetHeight : 0;
const liCount = liElements.length;
const totalHeight = liHeight * liCount;
ulChild.style.height = totalHeight + 'px';
} else {
const ulChild = this.querySelector('ul');
ulChild.style.height = '';
}
});
});
jQueryの場合
const openBtn = jQuery(".openbtn");
const gNav = jQuery(".gNav");
const hasChilds = jQuery(".has-child");
const level02 = jQuery(".level02");
openBtn.on("click", function() {
jQuery(this).toggleClass("active");
gNav.toggleClass("active");
});
hasChilds.on("click", function() {
jQuery(this).toggleClass("open");
if (jQuery(this).hasClass('open')) {
const ulChild = this.querySelector('ul');
const liElements = ulChild.querySelectorAll('li');
const liHeight = jQuery(liElements[0]).outerHeight();
const liCount = liElements.length;
const totalHeight = liHeight * liCount;
jQuery(ulChild).css('height', totalHeight + 'px');
} else {
const ulChild = this.querySelector('ul');
jQuery(ulChild).css('height', '');
}
});
他のHTML・CSS ・JavaScriptソースコード紹介記事まとめ
ソースコードまとめ
実務経験で作成したレイアウトのHTML・CSS ・JavaScriptソースコードを紹介した記事まとめています。