スマホ版サイトではおなじみのハンバーガーメニューの作り方を3行のjQueryを元に解説します。この方法を使ったハンバーガーメニューでは、言語ごとにHTMLはデータ、CSSは見た目、javascriptは状態遷移と明確に役割を分担して記述しています。昨今のVueやReactなどにみられるコンポーネント指向にも通ずる考え方ですので、ソースコードの内容も参考にするとよいです。長く使えるプログラムですので、コピペ用にブックマークしておいてください。
ハンバーガーメニューの完成デモ
まずはハンバーガーメニューのデモになります。HTMLとCSSとjQueryで実装しています。デモのボタンをクリックするとメニューが開き、もう一度押すとメニューが閉じます。スマホサイトでは頻出する定番のUIになります。
See the Pen 最もシンプルなハンバーガーメニュー実装方法01 by YutoSeta / ホームページ制作のエクレア (@yutoseta) on CodePen.
jQueryの実装内容を解説
jQueryを使う際には、scriptタグで事前にjQueryを読み込んでからでないと使えません。以下のCDNを読み込むことでjQueryが使えます。
<script src="https://code.jquery.com/jquery-3.4.1.js" integrity="sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=" crossorigin="anonymous"></script>
以下のリンクより、ダウンロードしてから使うこともできます。
jQuery公式サイト
https://code.jquery.com/
まずは、HTMLやCSSは無視してjQueryのコードのみご覧ください。
ハンバーガーメニューのデモとして実際に使用しているコードになります。
$('.menu-btn').on('click', function(){
$('.menu').toggleClass('is-active');
});
jqueryのonメソッドはユーザーの操作を検知して、なんらかの処理を実行します。今回は「.menu-btn」要素のクリックしたときに、toggleメソッドを実行しています。toggleClassメソッドでは「.menu」に「is-active」というクラスの付け外しをしています。is-activeがついている時はメニューが開いている状態、付いていない時はメニューが閉じている状態です。
つまりは、onメソッドとtoggleClassメソッドの組み合わせでクリックによってis-activeクラスの付け替えをしています。
jQueryとCSSの役割分担をしよう
今回のプログラムでは、メニューボタン(.menu-btn)をクリックしたら、メニュークラス(.menu)に任意のクラス(.is-active)の付け替えを行う、という処理しかjqueryには記述していません。クラスの付け替えのみでメニューの閉じ開きを実現しています。この付け替えするクラス「is-active」はメニューがアクティブな状態(開いている)とそうでない状態(閉じている)を表現するためのクラスになっています。HTMLとCSSが中心のウェブサイトでは、このようにしてjavascriptはなるべくクラスの付け替えだけで実現してあげるとプログラムがシンプルになります。
さて、.menuにis-activeというクラスが付け替えられているわけですが、ここでCSSをみてみましょう。以下の部分がクラスの付け替えによって書き換えられるスタイル部分です。
/*----------------------------
* アニメーション部分
*----------------------------*/
/* アニメーション前のメニューの状態 */
.menu{
transform: translateX(100vw);
transition: all .3s linear;
}
/* アニメーション後のメニューの状態 */
.menu.is-active{
transform: translateX(0);
}
transitionでは、アニメーション前のメニューの状態とアニメーション後のメニューの状態を0.3秒間かけて一定のスピード(linear)で変化させることでアニメーションを実現しています。
アニメーション前のメニューの状態(is-activeクラスが付いていないとき)はtransform:translateX(100vw);
で右に画面幅(100vw)分だけずらしています。これでメニューを閉じている時の位置にしています。
アニメーション後のメニューの状態(is-activeクラスがついているとき)はtransform:translateX(0);
として右にずれた分を元に戻しています。これでメニューを開いている時の位置にしています。
CSSでアニメーション前のメニューとアニメーション後のメニューを定義して、javascriptのクラスの付け替えでその状態を変化させる。というのがシンプルにハンバーガーメニューを実装するポイントです。
いろいろなメニュー開閉アニメーション
/* アニメーション前のメニューの状態 */
.menu{
transform: translateX(100vw);
transition: all .3s linear;
}
/* アニメーション後のメニューの状態 */
.menu.is-active{
transform: translateX(0);
}
See the Pen 最もシンプルなハンバーガーメニュー実装方法02 by YutoSeta / ホームページ制作のエクレア (@yutoseta) on CodePen.
/* アニメーション前のメニューの状態 */
.menu{
pointer-events: none;
opacity: 0;
transition: opacity .3s linear;
}
/* アニメーション後のメニューの状態 */
.menu.is-active{
pointer-events: auto;
opacity: 1;
}
/* アニメーション前のメニューの状態 */
.menu{
transform-origin: top left;
transform: rotateZ(-90deg);
transition: all .3s ease;
}
/* アニメーション後のメニューの状態 */
.menu.is-active{
transform: rotateZ(0deg);
}
See the Pen 最もシンプルなハンバーガーメニュー実装方法04 by YutoSeta / ホームページ制作のエクレア (@yutoseta) on CodePen.
/* アニメーション前のメニューの状態 */
.menu{
pointer-events: none;
opacity: 0;
transform-origin: center;
transform: scale(.5);
transition: all .3s ease;
}
/* アニメーション後のメニューの状態 */
.menu.is-active{
pointer-events: auto;
opacity: 1;
transform: scale(1.0);
}
まとめ
今回のような記述をすることでハンバーガーメニューの実装が3行になったように、javascriptの記述量を大幅に減らすことができます。タブメニューやアコーディオンメニュー、プルダウンメニュー、ありとあらゆる動きを伴うUIパーツはこのようなクラスの付け替えのみで再現できるのです。
ユーザーのアクション(イベント)によってコンポーネントの状態を切り替える。コンポーネントの状態が変わることで見た目も変わる。この考え方は昨今のjavascriptフレームワークで用いるコンポーネント指向と同じです。ぜひ、活用していってください。
この記事をかいてみての感想

javascriptやjQueryに関する質問やブログ記事として書いて欲しいテーマなどあれば、ぜひコメントから教えてください!
▼感想
コピペで済ませようと思ったらコピペ以上の深い設計の世界にいざなわれてしまった。みたいな、記事が本当は書きたかった。笑
▼書き足したい内容、記事のメモ
・タブメニューを4行で実装
・スライドショーをライブラリなしで実装する
・アコーディオンメニューを数行で実装
・ポップアップ、モーダルを
dsplay noneは使わなくてもできんですか?
display:none;
を使わずとも画面外にメニューを移動させて待機させておいて、クリックしたと同時に画面内に現れるようにすることで実現できます。
今回でいうと、
transform: translateX(100vw);
とすることで画面外にメニューが隠れています。
100vwは画面の横幅の大きさを表しています。
レスポンス化するときの、jQuery 側で記述するにはどうしますか?
・レスポンスしない時は綺麗に完成しました。
・「resize]やinnerWidthなど使いましたが、上手くいきませんでした。
loadイベントとresizeイベントの時に、
ロードした時の画面の横幅に応じて、
ハンバーガーメニューのプログラムを読み込んだり、
イベントの紐付けを解除したりすることで、
レスポンシブの場合でも誤動作を防ぐことができますね。
イベントの紐付け解除はjQueryのoffメソッドを使います。
https://api.jquery.com/off/
リクエストです!
入力フォームによく使われるステッププログレスバーに挑戦しているのですが、
次の項目を表示させたり、バリデート処理するためのJSと混ざってしまい、詰まっています。
同ページで項目の更新に伴って進むプログレスバーの実装方法についてご教授願います!
リクエストいただけて嬉しいです~😄
jsの処理とcssの処理を管理しやすくきちっとわけるのは、
特にそういったリッチなUIをつくると難しいですよね。
VueやReactを使った処理と通常のjavascriptを使った処理で記事にてご紹介できたらと思いますので、今しばらくお待ちください🙇💦💦