ドロワーメニュー(ハンバーガーメニュー)を簡単な jQueryとCSSだけで作る手順

ヘッダー部分のグローバルナビゲーションを、スマホビューの縦持ちの時だけドロワーメニュー(ハンバーガーメニュー)にしたくて、プラグインや既存ライブラリなどを使わない、ごくシンプルな作り方を調べました。
jQuery の「.toggleClass」を使えば、あとは CSS だけで簡単に作れることがわかったので、メモっておきます。

デモを作りました。(画像クリックで別ウィンドウで開きます)

スマホで見るならこちらから→

本日のINDEX

スポンサーリンク

クラス名を付与・解除できる jQueryの「.toggleClass」

ヘッダー部分のグローバルナビゲーションは、<nav>要素の中に <ul>を仕込んで作ります。
これを、PCビューの時は表示させて、ウィンドウ幅が小さくなった時には非表示にし、<nav>の表示・非表示のためのボタンを出す。
クリックで<nav>を表示するとともに自分自身の表示もにする。
次にボタンをクリックすると表示がに戻り、<nav>も非表示に戻る ってコトをしたいのですが、問題はこの「ボタンを押すたびに」表示を切り替えるのをどうするか…です。

ここで登場するのが jQueryの「.toggleClass」。
これは、指定した要素に指定したクラス名を付けたり消したりできるんです。
これを clickファンクションで使えば、クリックするたびにクラス名を付けたり消したりできる。すごいですね。消してもくれるんですね。

$('クリックする要素').click(function(){
	$('クラスを付ける要素').toggleClass('クラス名');
});

‘クリックする要素’ ‘クラスを付ける要素’ ともに、要素名(div とか)でも id(#menu とか)でも class名(.menu とか)でもOK。

参考サイト:
jQuery:toggleとtoggleClassを正しく使いこなす | hacknote
jQuery リファレンス:toggleClass

ドロワーメニューの動作の原理

まず、PCビューの時は、<nav> の中は <ul>要素で普通にメニューを作り、<li> は display:inline-block などで横並びにしておきます。

次にスマホビューの時はメディアクエリを使って、<nav> を非表示にし、ボタンを表示します。<nav> 内の <li> は display:block で縦並びにします。
ここで上記の jQueryの「.toggleClass」を使って、ボタンを押すたびに、親要素(<nav>とボタンの親)にクラス名を付けたり消したりします。
あとは CSS で指定しておけばOK
親要素にクラス名が無い時は、<nav>は非表示でボタンはハンバーガー状態
親要素にクラス名が付いている時は、<nav>を表示してボタンは×状態に指定します。

これだけでもイイのですが、transitionプロパティでなめらかに動くようにしても面白いですね。

ドロワーメニューの作り方

では、 DEMO ページのドロワーメニューの作り方をメモっておきます。

CSSでボタンを作っておく

デモページでは、<header>を親要素にしています。
この中に <h1>、<nav>がありますが、ここにもう1つ <div>を追加して id="navToggle" を付けておきました。この<div>の中に入っている3つの <span> は、CSSで三本線にします。

<header>
<h1><a href="index.html"><img src="img/header_logo.png"></a></h1>
<div id="navToggle">
  <div>
   <span></span> <span></span> <span></span>
  </div>
</div><!--#navToggle END-->
<nav>
  <ul>
   <li><a href="#">HOME</a></li>
   <li><a href="#">MENU1</a></li>
   <li><a href="#">MENU2</a></li>
   <li><a href="#">MENU3</a></li>
   <li><a href="#">MENU4</a></li>
  </ul>
</nav>
</header>

ボタンのCSSです。

#navToggle {
	display:none; /*通常時は非表示にしておきます*/
	position:absolute; /*bodyに対しての絶対位置指定です*/
	right:13px;
	top:13px;
	width:30px;
	height:25px;
	cursor:pointer}
#navToggle div {position:relative} /*spanの絶対位置指定の親にします*/
#navToggle span {
	display:block;
	position:absolute; /*#navToggle div に対して*/
	width:100%;
	border-bottom:solid 3px #999;
	-webkit-transition: .35s ease-in-out;
	-moz-transition: .35s ease-in-out;
	transition: .35s ease-in-out}
#navToggle span:nth-child(1) {top:0}
#navToggle span:nth-child(2) {top:11px}
#navToggle span:nth-child(3) {top:22px}

ボタンの div#navToggleは、通常時は display:noneで非表示にします(2行目)。
position:absolute で上や右から少し離して配置しておきます。

三本線のための <span>は、borderを指定して(14行目)、親の divに対して幅は100%(13行目)、位置は上から順に絶対位置指定で決めてやって(18〜20行目)等間隔に並べます。

transition の指定は(15〜17行目)、あとで×に動かす時に、なめらかなアニメーション風にするための設定です。

これで、ボタンは存在するけど画面上は見えない状態になりました。

次は、<header> や <nav>のCSSです。
デモページでは、<header> を display:tableに、<h1> と <nav>を display:table-cellにして横に並べています。
<nav>には text-align:rightを指定してメニューを右に寄せています。
<li>は display:inline-blockで横並びにしています。

/*header footer*/
header, footer {
	width:100%;
	z-index:2;
	position:fixed;
	background:rgba(255,255,255,.7)}
footer {/*略/}
/*header menu*/
header {
	display:table;
    font-size:0; /*ul,liが親のfont-sizeを継承して隙間が空くのをリセット*/
    line-height:0}
header h1, nav {
	display:table-cell}
nav {
	text-align:right;
    vertical-align:bottom}
header h1 a img {
	height:40px;
    margin:10px}
header ul {
	font-size:13px;
    line-height:1;
    margin:0 10px 10px 0}
header ul li {
    margin-left:3px;
    display:inline-block}
header ul li::after {content:' |'}
header ul li:last-child::after {content:''}
header ul li a {color:inherit}

jQuery と「.toggleClass」をHTMLファイルに記述

ボタンをクリックした時の動作の準備です。
HTMLの <head>内に jQuery を読み込んでおきます(1行目)。
その後に「.toggleClass」も書いておきます(2〜8行目)。(外部ファイルにしても)

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(function() {
	$('#navToggle').click(function(){//headerに .openNav を付加・削除
		$('header').toggleClass('openNav');
	});
});
</script>
</head>

デモページでは、ボタン(#navToggle)を押すたびに、<header>に クラス名「.openNav」を付けたり消したりするように指定しています。

CSSで <header>にクラスが付いた時の表示を指定

さてあとは、メディアクエリで ウィンドウ幅が狭くなった時の指定をするだけです。

ボタンを表示し、メニューは一旦非表示にします。
ボタンを押すと親要素にクラスが付くのを利用して、メニューが表示され、ボタンがに切り替わる指定も加えます。

@media screen and (max-width: 640px) {

/*header menu*/
 /*nav要素は絶対位置指定にして、ビューの外側に置いて見えなくします。
  nav の中の ul li は横並びを解除して縦組みにレイアウトし直します。*/
header nav {
	position: absolute; /*bodyに対しての絶対位置*/
	right:0;
    top: -300px; /*通常時はビュー外*/
	background:rgba(255,255,255,.7);
    width:50%;
	padding:0 10px;
	-webkit-transition:.5s ease-in-out; /*transitionで動きを*/
	-moz-transition:.5s ease-in-out;
	transition:.5s ease-in-out;
	text-align:left}
header ul {margin:0}
header ul li {
	display:block;
    margin:0;
    border-bottom:dotted 1px #fff;
    line-height:3}
header ul li a {display:block}
header ul li::after {content:''}
header ul li:last-child {border-bottom:none}

/* Toggle(Button) */
/*display:noneだったボタンを display:blockにして表示します*/
#navToggle {display:block}

/* Click Toggle(Button) */
 /*ここから jQueryで header要素に付けた「.openNav」を利用します*/
 /*.openNavが付いた要素内のボタン(#navToggle)内のspanへの指定*/
 /*最初のspanをマイナス45度に*/
.openNav #navToggle span:nth-child(1) {
	top: 11px;
	-webkit-transform:rotate(-45deg);
	-moz-transform:rotate(-45deg);
	transform:rotate(-45deg)}
 /*2番目と3番目のspanを45度に*/
.openNav #navToggle span:nth-child(2),
.openNav #navToggle span:nth-child(3) {
	top: 11px;
	-webkit-transform:rotate(45deg);
	-moz-transform:rotate(45deg);
	transform:rotate(45deg)}

/*header menu*/
 /*.openNavが付いた要素の中のnavを 縦方向に351px移動(=表示される)*/
.openNav nav {
	-moz-transform: translateY(351px);
	-webkit-transform: translateY(351px);
	transform: translateY(351px)}
}

この↑あと再び ボタン(.openNav #navToggle)を押せば、jQuery によって親のクラス(.openNav)が削除されるので、最初のボタンの設定(#navToggle)に戻るというわけです。
navも同様に ボタンを押すたびに .openNav nav と nav の指定に切り替わります。

<nav>のy方向の移動で(51〜54行目)351px移動させていますが、これは、
<header>の高さが50px、<nav>のビュー外での位置は-300pxなので、合計350px動かせば良いのですが、1px分<header>と離してラインを入れたかったので351pxにしました。

ハンバーガー部分のCSS参考サイト

ハンバーガーボタンのにするCSSは、いろいろアレンジができそうですね。
いろいろ考えたソースを公開してくださってるサイトがありましたので、リンクを貼っておきます。参考にさせていただきたいと思います。

真ん中の棒がピューっと飛んでいく のを使ってみたい↓ 株式会社LIGさんです。
ひたすらハンバーガーアイコンを作ったので9種のソースを公開します! | 株式会社LIG

デモがページ内でとてもわかりやすい↓ NxWorldさんです。
CSSで実装するハンバーガーメニュークリック時のエフェクト 10+ | NxWorld

こちらもNxWorldさん↓ ラインがサークルになるのが素敵です。
CSSで実装するハンバーガーメニューアイコンの見栄えやクリック・ホバー時のエフェクト 10 | NxWorld

関連記事

モーダルウィンドウ(ポップアップウィンドウ)をjQueryとCSSで簡単に作る手順

プラグインなどを使わずに簡単にモーダルウィンドウを設定する方法を探していたところ、バッチリのjsソースを見つけました。 ウィンドウの高さの取得や、オーバーレイ [記事を読む]

background-attachment: fixed がスマホで効かない問題は ::before で解決!

Webページの背景画像を、background-size: cover で background-attachment: fixed にしたいとき、PCブラ [記事を読む]

display:table-cell の親に display:table を指定しないと意味無い

CSSのfloatを解除するclearfix で「display:table」を使いました。 clearfixでは、table内のセル(trやtd)が0な [記事を読む]

Comments

  1. yata より:

    始めまして。
    こちらに記載されているドロワーメニューを利用させていただきました。
    ご丁寧な説明書きで非常にわかりやすかったのですが、HTMLに関して携わり始めてまだ間もなく、一部どうしても上手く反映できない箇所がありましたので、ご質問させていただきました。
    内容は、メニューをクリックした時に下に表示される項目が、縦並びにならずに横並びになってしまいます。何度も見返してみても、なかなか上手く反映されません。
    お応えできる範囲で構いませんので、お力添えをいただければ幸いです。
    お忙しいところ恐れ入りますが、宜しくお願い致します。

    • yuki★hata より:

      yataさん
      要素の 縦or横並びという基本でハマっておられるようですが、CSSをよく調べてみて。 この記事では displayプロパティを使っています。

  2. yata より:

    ご報告が遅れましたが、やっと出来ました。
    まだまだ勉強不足ですが、少しづつでも頑張ってみます。
    助言していただき、有難うございました。

Leave a Comment

入力エリアすべてが必須項目です。メールアドレスが公開されることはありません。

内容をご確認の上、送信してください。

^