今回は、ハンバーガーボタンをクリックすると表示・非表示が切り替えられるグローバルナビの実装方法を紹介します。
↓↓こんな感じです。DEMOの右上にあるハンバーガーボタンをクリックしてみて下さい。
よく使うデザインですね。
ハンバーガーメニューの実装方法
それでは実装方法を解説していきます。
HTML
<header class="header">
<nav class="global-nav">
<ul class="global-nav__list">
<li class="global-nav__item"><a href="">メニュー1</a></li>
<li class="global-nav__item"><a href="">メニュー2</a></li>
<li class="global-nav__item"><a href="">メニュー3</a></li>
<li class="global-nav__item"><a href="">メニュー4</a></li>
<li class="global-nav__item"><a href="">メニュー5</a></li>
</ul>
</nav>
<div class="hamburger" id="js-hamburger">
<span class="hamburger__line hamburger__line--1"></span>
<span class="hamburger__line hamburger__line--2"></span>
<span class="hamburger__line hamburger__line--3"></span>
</div>
<div class="black-bg" id="js-black-bg"></div>
</header>
headerの中に、グローバルナビ(.global-nav)とハンバーガー(.hamburder)、黒背景(.black-bg)を作ります。
CSS
.header {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 40px;
background-color: #fff;
box-shadow: 0 2px 6px rgba(0,0,0,.16);
}
.global-nav {
position: fixed;
right: -320px; /* これで隠れる */
top: 0;
width: 300px; /* スマホに収まるくらい */
height: 100vh;
padding-top: 40px;
background-color: #fff;
transition: all .6s;
z-index: 200;
overflow-y: auto; /* メニューが多くなったらスクロールできるように */
}
.hamburger {
position: absolute;
right: 0;
top: 0;
width: 40px; /* クリックしやすいようにちゃんと幅を指定する */
height: 40px; /* クリックしやすいようにちゃんと高さを指定する */
cursor: pointer;
z-index: 300;
}
.global-nav__list {
margin: 0;
padding: 0;
list-style: none;
}
.global-nav__item {
text-align: center;
padding: 0 14px;
}
.global-nav__item a {
display: block;
padding: 8px 0;
border-bottom: 1px solid #eee;
text-decoration: none;
color: #111;
}
.global-nav__item a:hover {
background-color: #eee;
}
.hamburger__line {
position: absolute;
left: 11px;
width: 18px;
height: 1px;
background-color: #111;
transition: all .6s;
}
.hamburger__line--1 {
top: 14px;
}
.hamburger__line--2 {
top: 20px;
}
.hamburger__line--3 {
top: 26px;
}
.black-bg {
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
z-index: 100;
background-color: #000;
opacity: 0;
visibility: hidden;
transition: all .6s;
cursor: pointer;
}
/* 表示された時用のCSS */
.nav-open .global-nav {
right: 0;
}
.nav-open .black-bg {
opacity: .8;
visibility: visible;
}
.nav-open .hamburger__line--1 {
transform: rotate(45deg);
top: 20px;
}
.nav-open .hamburger__line--2 {
width: 0;
left: 50%;
}
.nav-open .hamburger__line--3 {
transform: rotate(-45deg);
top: 20px;
}
長い!長いのであとで詳しく解説します。
JavaScript
function toggleNav() {
var body = document.body;
var hamburger = document.getElementById('js-hamburger');
var blackBg = document.getElementById('js-black-bg');
hamburger.addEventListener('click', function() {
body.classList.toggle('nav-open');
});
blackBg.addEventListener('click', function() {
body.classList.remove('nav-open');
});
}
toggleNav();
これでハンバーガーメニュー(トグルメニュー)が完成しました。
ハンバーガーがクリックされると、nav-openというクラスがbodyに付与されます。
再度クリックするとnav-openというクラスが削除されます。(要素.classList.toggle)
つまり、body class=”nav-open”の時に、グローバルナビが出てくるように実装するのです。
CSSの詳しい解説
HTMLとJavaScriptは難しくありませんが、CSSは少し解説が必要かと思います。
.global-nav {
position: fixed;
right: -320px; /* これで隠れる */
top: 0;
width: 300px; /* スマホに収まるくらい */
height: 100vh;
padding-top: 40px;
background-color: #fff;
transition: all .6s;
z-index: 200;
overflow-y: auto; /* メニューが多くなったらスクロールできるように */
}
まずはメニューの実装方法。300pxならどのスマホでもはみ出ずに表示できます。
right: -320px; で、一旦画面の外に追いやります。
overflow-y: auto; は、メニューが増えることによりデバイスの高さよりも長くなっても、スクロールで見られるようにするためです。
.hamburger {
position: absolute;
right: 0;
top: 0;
width: 40px; /* クリックしやすいようにちゃんと幅を指定する */
height: 40px; /* クリックしやすいようにちゃんと高さを指定する */
cursor: pointer;
z-index: 300;
}
ちゃんと幅と高さを指定することで、クリックしやすくします。
メニューで隠れないように、z-indexを300にして上に表示されるようにしています。
.black-bg {
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
z-index: 100;
background-color: #000;
opacity: 0;
visibility: hidden;
transition: all .6s;
cursor: pointer;
}
ここはクリックした時にメニューの下に表示される半透明の黒背景です。
メニューを見やすくするためと、メニューを閉じやすくするために黒背景があったほうが良いでしょう。
デモを見ていただければ分かると思いますが、黒背景があった方がメニューを閉じるのが楽です。
/* 表示された時用のCSS */
.nav-open .global-nav {
right: 0;
}
.nav-open .black-bg {
opacity: .8;
visibility: visible;
}
.nav-open .hamburger__line--1 {
transform: rotate(45deg);
top: 20px;
}
.nav-open .hamburger__line--2 {
width: 0;
left: 50%;
}
.nav-open .hamburger__line--3 {
transform: rotate(-45deg);
top: 20px;
}
これはメニューが表示される時のスタイルです。
JavaScriptでbodyにnav-openクラスが加えられると、このスタイルが適用されるという仕組みです。
ハンバーガーの棒を回転させる
ちなみに、上のコードに少し手を加えて、
.nav-open .hamburger__line--1 {
transform: rotate(405deg);
top: 20px;
}
.nav-open .hamburger__line--3 {
transform: rotate(-405deg);
top: 20px;
}
rotateの角度に360度足すと(引くと)、ハンバーガーの棒が一回転します。
そもそもハンバーガーメニューってどうなの?
とまあ長々と解説してきましたが、「そもそもハンバーガーメニューってUI的に微妙」という話もあります。
- メニューが隠れて一見してその存在に気付きにくい。
- クリックしないと何が起こるのか分かりずらい。
という理由からです。
横幅が広々使えるPCならハンバーガーメニューの利用は避けるのが無難です。
スマホサイトでも、メニューが二つ三つくらいなら、横並びで表示させてもいいでしょう。
個人的には「ユーザーもそろそろハンバーガーメニューに慣れているだろう」とは思いますけどね。
まとめ
賛否両論ありますが、メニューが収まらないのであればハンバーガーメニューにしてしまって問題ないでしょう。
よく使われるデザインなので、サクッと作れるようにしておきましょう。
他にもこんな記事があります。