私はjQueryが苦手です。ハンバーガーメニューを作る際も、スライドインなのかフェードインなのか、右から出るのか左から出るのか、閉じる時はどこをクリックするかなどの細かい違いで毎回調べるのに時間がかかってしまいます。
自分用のメモにいろいろなハンバーガーメニューをまとめました。
基本のHTML・CSS・JS
まずはベースとなるHTML・CSS・JSを書きました。いちおうレスポンシブです。これを、やりたい動きに合わせて修正していきます。
動きに合わせてメニューやボタンの位置が変わるので、この時点ではまだメニューは隠していません。
HTML
ベースのHTML・CSSはこのようになるようにつくりました。

<body>
<header>
<nav>
<ul class="menu">
<li class="menu-list">メニュー1</li>
<li class="menu-list">メニュー2</li>
<li class="menu-list">メニュー3</li>
<li class="menu-list">メニュー4</li>
<li class="menu-list">メニュー5</li>
</ul>
</nav>
<div class="btn">
<span></span>
<span></span>
<span></span>
</div>
</header>
<div class="content">
</div>
</body>
CSS
header {
width: 100%;
height: 50px;
background-color: #d5c9bd;
}
body.noscroll{
overflow: hidden;
}
.content {
width: 100%;
}
.menu {
position: fixed;
top: 0;
left: 0;
width: 50%;
height: 100%;
min-height: 100vh;
padding: 60px 0;
color: #000;
background-color: #f4f1ee;
transition: .3s;
}
.menu.open {
}
.menu-list {
font-size: 16px;
line-height: 1;
padding: 1.5em 1.5em;
}
.btn {
display: block;
width: 50px;
height: 50px;
position: relative;
z-index: 3;
border:none;
}
.btn span {
width: 30px;
height: 3px;
display: block;
position: absolute;
left: 50%;
transform: translateX(-50%);
background-color: #fff;
}
.btn span:nth-child(1) {
top: 13px;
}
.btn span:nth-child(2) {
top: 50%;
transform: translate(-50%,-50%);
}
.btn span:nth-child(3) {
bottom: 13px;
}
jQuery
toggleClassを利用して、btnをクリックしたら、menuに「open」のclassをつける・外すというようになっています。背景のコンテンツがスクロールしないようにbodyにも「noscroll」のclassをつけます。
$(document).ready(function(){
$('.btn').on('click',function(){
$('.menu').toggleClass('open');
$('body').toggleClass('noscroll');
});
});
このベースに手入れしてハンバーガーメニューに動きをつけていきます。
メニューの出方の違い4パターン
左右上のスライドインと、画面からフェードインの4種類を書きました。
下からはあまりないかなと思って入れませんでしたが上と逆の記述をすれば大丈夫。
左からスライドイン
左からスライドインしてメニューを表示するパターン。ベースのjQueryはいじらず、CSSのみの編集です。
メニューを左側に隠す記述と、openのclassをつけた時の記述を追加しました。
.menu {
position: fixed;
top: 0;
left: 0;
width: 50%;
height: 100%;
min-height: 100vh;
padding: 60px 0;
color: #000;
background-color: #f4f1ee;
transition: .3s;
/* スライドイン */
-webkit-transform: translateX(-110%);
-ms-transform: translateX(-110%);
transform: translateX(-110%);
-webkit-transform: translateX(-110%) translateZ(0);
-webkit-transition: -webkit-transform 500ms 0s ease;
transition: -webkit-transform 500ms 0s ease;
transition: transform 500ms 0s ease;
transition: transform 500ms 0s ease, -webkit-transform 500ms 0s ease;
-webkit-overflow-scrolling: touch;
}
.menu.open {
-webkit-transform: translateX(0%);
-ms-transform: translateX(0%);
transform: translateX(0%);
overflow-x: hidden;
}
右からスライドイン
右からスライドインしてメニューを表示するパターン。ベースのjQueryはいじらず、CSSのみの編集です。
ボタンを右側に移動。メニューを右側に隠す記述と、openのclassをつけた時の記述を追加しました。
.menu {
position: fixed;
top: 0;
right: 0;
width: 50%;
height: 100%;
min-height: 100vh;
padding: 60px 0;
color: #000;
background-color: #f4f1ee;
transition: .3s;
/* スライドイン */
-webkit-transform: translateX(110%);
-ms-transform: translateX(110%);
transform: translateX(110%);
-webkit-transform: translateX(110%) translateZ(0);
-webkit-transition: -webkit-transform 500ms 0s ease;
transition: -webkit-transform 500ms 0s ease;
transition: transform 500ms 0s ease;
transition: transform 500ms 0s ease, -webkit-transform 500ms 0s ease;
-webkit-overflow-scrolling: touch;
}
.menu.open {
-webkit-transform: translateX(0%);
-ms-transform: translateX(0%);
transform: translateX(0%);
overflow-x: hidden;
}
.btn {
display: block;
width: 50px;
height: 50px;
position: absolute;
right: 0;
z-index: 3;
border:none;
}
上からスライドイン
上からスライドインしてメニューを表示するパターン。ベースのjQueryはいじらず、CSSのみの編集です。
メニューを横幅100%にして文字を中央寄せにし、openのclassをつけた時の記述を追加しました。
.menu {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
min-height: 100vh;
padding: 60px 0;
color: #000;
background-color: #f4f1ee;
transition: .3s;
/* スライドイン */
-webkit-transform: translateY(-110%);
-ms-transform: translateY(-110%);
transform: translateY(-110%);
-webkit-transform: translateY(-110%) translateZ(0);
-webkit-transition: -webkit-transform 500ms 0s ease;
transition: -webkit-transform 500ms 0s ease;
transition: transform 500ms 0s ease;
transition: transform 500ms 0s ease, -webkit-transform 500ms 0s ease;
-webkit-overflow-scrolling: touch;
}
.menu.open {
-webkit-transform: translateY(0%);
-ms-transform: translateY(0%);
transform: translateY(0%);
overflow-x: hidden;
}
.menu-list {
font-size: 16px;
line-height: 1;
padding: 1.5em 0;
text-align: center;
}
その場でフェードイン
その場でフェードインしてメニューを表示するパターン。ベースのjQueryはいじらず、CSSのみの編集です。
openのclassをつけた時の記述を追加しました。メニューはopacityで透過しています。デザインの微調整でメニューを横幅100%にして文字を中央寄せにしました。
.menu {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
min-height: 100vh;
padding: 60px 0;
color: #000;
background-color: #f4f1ee;
transition: .3s;
/* フェードイン */
opacity: 0;
transition: opacity .6s ease, visibility .6s ease;
}
.menu.open {
visibility: visible;
opacity: 1;
}
.menu-list {
font-size: 16px;
line-height: 1;
padding: 1.5em 0;
text-align: center;
}
閉じ方の違い2パターン
上記はひとつのボタンで開閉しますが、別のメニューの閉じ方の例です。
メニューと別のボタンをクリックで閉じる
ハンバーガーボタンと別に、メニュー内に閉じるボタンがある時の例です。

<CSS>
閉じるボタンのCSSを追加し、メニューは左からスライドインのCSSを書いておきます。開くと閉じるのボタンが別々なので、開くボタンを右側に変更しました。
デモだとcontentの中身がないのでheightを追加していますが、実際は必要ないはずです。
.content {
width: 100%;
height: 100%;
min-height: 90vh;
}
.menu {
position: fixed;
top: 0;
left: 0;
width: 50%;
height: 100%;
min-height: 100vh;
padding: 60px 0;
color: #000;
background-color: #f4f1ee;
transition: .3s;
/* スライドイン */
-webkit-transform: translateX(-110%);
-ms-transform: translateX(-110%);
transform: translateX(-110%);
-webkit-transform: translateX(-110%) translateZ(0);
-webkit-transition: -webkit-transform 500ms 0s ease;
transition: -webkit-transform 500ms 0s ease;
transition: transform 500ms 0s ease;
transition: transform 500ms 0s ease, -webkit-transform 500ms 0s ease;
-webkit-overflow-scrolling: touch;
}
.menu.open {
-webkit-transform: translateX(0%);
-ms-transform: translateX(0%);
transform: translateX(0%);
overflow-x: hidden;
}
.btn {
display: block;
width: 50px;
height: 50px;
position: absolute;
right: 0;
z-index: 3;
border:none;
}
.closebtn {
display: inline-block;
vertical-align: middle;
color: #333;
line-height: 1;
width: 1em;
height: 0.1em;
background: currentColor;
position: absolute;
top: 20px;
right: 10px;
transform: rotate(45deg);
}
.closebtn::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: inherit;
transform: rotate(90deg);
}
<JS>
addClass、removeClassを使用しました。btn(メニューボタン)をクリックで「open」のClassをつけ、closebtn(閉じるボタン)をクリックでClassを外すようにしています。
$(document).ready(function(){
$('.btn').on('click',function(){
$('.menu').addClass('open');
$('body').addClass('noscroll');
});
$('.closebtn').on('click',function(){
$('.menu').removeClass('open');
$('body').removeClass('noscroll');
});
});
領域外をクリックでも閉じる
上記の仕様で、メニューを開いたときに閉じるボタンだけでなく領域外(メニューエリア以外)をクリックしても閉じるようにしました。
contentをクリックしたときに、menuに「open」のClassが付いていたら外すというつくりです。
デモページ(上記と同じ)
$(document).ready(function(){
$('.btn').on('click',function(){
$('.menu').addClass('open');
$('body').addClass('noscroll');
});
$('.closebtn').on('click',function(){
$('.menu').removeClass('open');
$('body').removeClass('noscroll');
});
//メニュー以外をクリックで閉じる
var nav = $('.menu');
$('.content').click(function() {
if(nav.hasClass('open')) {
$('.menu').removeClass('open');
}
});
});
メニューボタンの動き
三本線から×印に
メニューボタンをクリックしたときに三本線から×印になる動きを追加しました。クリック時にJSで「open」のClassを追加し、CSSのrotateで形を変えました。
<CSS>
.btn span {
width: 30px;
height: 3px;
display: block;
position: absolute;
left: 50%;
transform: translateX(-50%);
background-color: #fff;
transition: .3s;
}
.btn.open span {
left: 22%;
}
.btn.open span:nth-child(1) {
top: 23.5px;
transform: rotate(45deg);
}
.btn.open span:nth-child(2) {
opacity: 0;
}
.btn.open span:nth-child(3) {
bottom: 23.5px;
transform: rotate(-45deg);
}
<JS>
$(document).ready(function(){
$('.btn').on('click',function(){
$('.btn').toggleClass('open');
$('.menu').toggleClass('open');
$('body').toggleClass('noscroll');
});
});
まとめ
すぐやり方を忘れてしまうので、自分用のメモにまとめました。jQueryとCSSのアニメーション、もう少し慣れていきたいです。