【jQuery】プラグインを使わずに、簡単にサイドからスライドして現れるメニューを実装する(ほぼCSS)
最近はモーダルっぽい感じでメニューをページ全体に表示するパターンが増えてる気がするし、もう随分色々な方法やプラグインがあって、かなり今さらなネタですけど、クリックでサイドからスライドして現れるメニューの新たな知見を得たので書き残しておきたいと思います。
「新たな知見」といっても、誰でも考えつくようなことで、そんなに大したことではなく、「あぁ、なるほど」とちょっと思った程度のことですが。。。
クリックでサイドから現れるメニューとは
何て言う名前なのか良く分からないので、デモを。デモページ右上の三つの四角いボタンをクリックすると、にょきっと横からスライドして現れるやつがそうです。
jQueryを利用していますが、クリック時にクラスを付与しているだけで、ほとんどCSSの力です。
今まではこれを実装するのに、サイドメニュー自体にposition
やtransform
でネガティブな値を与えて画面からはみ出させていたんですが、まぁ別にそれでも全然いいんですが、はみ出ているという状態に少し違和感があったんですよね。全く問題ないんでしょうけど。
実装
新たな知見と言うと本当に大げさなんですが、簡単に言えば、z-index
を使ってサイド部分をメインコンテンツの下に潜り込ませるという単純な方法でして、これを知った時「あぁ、なるほどね」となったのでした。
なので、サイドからスライドして現れるというよりも、メインのコンテンツ部分をスライドさせて(下にあった)メニューを表示させると言ったほうが正解かもしれません。
HTML
<body>
<!-- サイドオープン時メインコンテンツを覆う -->
<div class="overlay" id="js__overlay"></div>
<!-- サイドメニュー -->
<nav class="side-menu">
<ul>
<li><a href="#">メニュータイトル</a></li>
<li><a href="#">メニュータイトル</a></li>
<li><a href="#">メニュータイトル</a></li>
</ul>
</nav>
<!-- 開閉用ボタン -->
<div class="side-menu-btn" id="js__sideMenuBtn"></div>
<!-- メインコンテンツ -->
<div class="wrapper">
<header class="header">
<h1>ヘッダータイトル</h1>
<p>ヘッダー</p>
</header>
<main class="contents">
<section class="contents__inner">
<h1>コンテンツタイトル</h1>
<p>コンテンツ</p>
</section>
<section class="contents__inner">
<h1>コンテンツタイトル</h1>
<p>コンテンツ</p>
</section>
<section class="contents__inner">
<h1>コンテンツタイトル</h1>
<p>コンテンツ</p>
</section>
</main>
<footer class="footer">
<p>フッター</p>
</footer>
</div>
</body>
最近はあまりやらないんですけど、div.wrapper
でコンテンツ部分を全て囲んでしまっています(楽なので)。
ポイントは、メニュー部分を独立させているところ。こういったメニューはheader
の中に入れたいところですけど、入れるとこの方法は使えません。
CSS
/* サイドオープン時にメインコンテンツを覆う部分 */
.overlay {
content: '';
visibility: hidden;
position: fixed;
top: 0;
left: 0;
display: block;
width: 100%;
height: 100%;
background: rgba(0,0,0,0);
-webkit-transition: all .5s ease;
transition: all .5s ease;
z-index: 3;
}
.overlay::after {
content: "この部分をクリックで閉まる";
visibility: hidden;
position: fixed;
top: 40%;
left: 0;
display: block;
width: 100%;
height: 50px;
color: rgba(255,255,255,0);
font-size: 40px;
font-weight: bold;
text-align: center;
-webkit-transition: all .5s ease;
transition: all .5s ease;
}
.side-open .overlay {
visibility: visible;
cursor: pointer;
background: rgba(0,0,0,.7);
}
.side-open .overlay::after {
visibility: visible;
color: rgba(255,255,255,.8);
}
/* サイドメニュー ※リストのスタイルは省略 */
.side-menu {
position: fixed;
top: 0;
right: 0;
width: 300px;
height: 100%;
padding-top: 150px;
text-align: left;
font-size: 13px;
background: #2A408E;
z-index: 1;
}
/* 開閉用ボタン ※ボタンの細かいスタイルは省略 */
.side-menu-btn {
position: fixed;
top: 20px;
right: 20px;
width: 40px;
height: 40px;
padding: 5px;
background: #ccc;
cursor: pointer;
z-index: 4;
}
/* メインコンテンツ */
.wrapper {
position: relative;
width: 100%;
height: 100%;
text-align: center;
font-size: 13px;
background: #F8F8F8;
-webkit-transition: all .5s ease;
transition: all .5s ease;
z-index: 2;
}
/* メインコンテンツ内のスタイル ※デザインに併せて適当に */
.header {
padding: 100px 0;
background: #161616;
color: #fff;
}
.header h1,
.contents h1 {
margin-bottom: 30px;
font-size: 20px;
}
.contents {
width: 100%;
padding: 150px 0;
background: #f5f5f5;
}
.contents p {
margin-bottom: 50px;
}
.footer {
padding: 150px 0;
background: #fff;
}
/* サイドメニューオープン */
.side-open .wrapper,
.side-open .overlay {
-webkit-transform: translate3d(-300px, 0, 0);
transform: translate3d(-300px, 0, 0);
}
細かい部分は省略しています。CSSでのポイントは、z-index
です。z-index
の値で重なりの順序を決めています。なお、div.overlay
は、おまけみたいなものなので、無くてもいいと思います。
JS
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
$(function () {
var $body = $('body');
$('#js__sideMenuBtn').on('click', function () {
$body.toggleClass('side-open');
$('#js__overlay').on('click', function () {
$body.removeClass('side-open');
});
});
});
</script>
jQueryで、ボタンがクリックされた時にbody
へside-open
というクラスを付与しています。クラスが付与されると、CSSで用意していた、
.side-open .wrapper,
.side-open .overlay {
-webkit-transform: translate3d(-300px, 0, 0);
transform: translate3d(-300px, 0, 0);
}
が、有効になりメインコンテンツ部分が300px左へスライドし、サイドメニューが現れるという仕組みになっています。
jQueryのバージョンを見れば分かると思いますが、IE8以下は全く考えていません。でも、jQueryのバージョンを変えて、CSSのtransform
のところをなんとかすれば(アニメーションは効かないけど)なんとかなるんじゃないかなと思います。
デモ
上記のデモは、以下のリンクから見れます。デモは多少リッチな仕様となっています。
プラグインは使わない
サイドメニューをスライドさせて表示する系のプラグインはたくさんありますが、結構余計な機能とかも入っていて、ちょっとあれなんですよね。IE8とか対応させるなら、プラグインを使った方が楽かもしれませんが、最近はプラグインを使わずに、どんなものでも極力自分で作るようにしています。
おわり
初めにも書いたけど、この手の「しまっていたメニューを表示する」機能は、モーダルで表示するのが最近多いですよね。どっちが使いやすいのかは分からないですけど、今回の方法でCSSだけ変えれば簡単に実装できますね。
どうやらドロワーメニューとか言うらしいことが最後に分かりました。