ドロワーメニューとは、スマートフォンサイトでボタンをクリックすると左からもしくは右からスライドして現れるナビゲーションを格納しているメニューの事です。近年はおしゃれ感もありPCサイトでも復旧しています。イラストは右から左にスライドインしてくる例です。
以前ならJavaScriptで試行錯誤とやり方に苦労ありますが、これくらいはCSSで仕組みとアニメーションを考えるのみでとても簡単です。それでは基本的仕組みをご説明させていただきます。まずドロワーメニューを表示領域外に設置しましょう。
position:fixedを利用してドロワーメニュー分の横幅を表示領域外にマイナス設置します。参考でいうところは右から左にスライドインしますので、right:-横幅サイズ分となります。
ハンバーガーボタンがクリックされたらCSSを追加というアニメーションのエンジンはJSで書きますので、先にアニメーションの仕組みをCSSで構造しましょう。ボタンがクリックされると領域に出したいとする場合、rightが0となれば、右端を基準に表示領域に戻ります。そのためにアニメーション発動のキーを用意します。よく私はトリガーと呼びます。母体にトリガーがあればアニメーション発動し、なければアニメーションせずもとの姿のまま、今回はbodyタグにトリガーがあればとして進めます。
どうでしょうか。トリガーとCSSアニメーションを使えば、いろいろなアニメーションが対応できます。発動するCSSを構造し、JSでクリックしたときやホバーをしたときのトリガーとなるスクリプトを書くだけです。単純な仕組みですね。
それでは実装について確認してみましょう。まずはマークアップを下記例とします。
<div id="wrap">
<section>
<button type="button" id="hamburger">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<nav class="menu">
<ul>
<li><a href="">NAVI01</a></li>
<li><a href="">NAVI02</a></li>
<li><a href="">NAVI03</a></li>
<li><a href="">NAVI04</a></li>
</ul>
</nav>
</section>
<main id="contents">
<section>
コンテンツ
</section>
</main>
</div><!-- wrap -->
ハンバーガーボタンとドロワーメニューを用意して、mainタグがあるだけのシンプルなマークアップです。
#contents{
width: 100%;
height: 100vh;
background: #F6F1D2;
display: flex;
justify-content: center;
align-items: center;
transform: translateX(0);
transition: all 400ms cubic-bezier(1.000, 0.000, 0.000, 1.000);
}
#hamburger {
cursor: pointer;
display: block;
position: fixed;
z-index: 2;
top: 1rem;
right: 1rem;
background: transparent;
width: 3rem;
height: 2.8rem;
border: none;
& .icon-bar{
position: absolute;
left: 0;
width: 100%;
height: 4px;
border-radius: 4px;
background: #000;
transition: all 400ms cubic-bezier(1.000, 0.000, 0.000, 1.000);
&:nth-child(1) {
top: 0;
}
&:nth-child(2) {
top: 20px;
}
&:nth-child(3) {
bottom: 0;
}
}
&.active{
& .icon-bar{
background: #000;
&:nth-child(1) {
background: #fff;
transform: translateY(20px) rotate(-45deg);
}
&:nth-child(2) {
opacity: 0;
}
&:nth-child(3) {
background: #fff;
transform: translateY(-20px) rotate(45deg);
}
}
}
}
.menu {
position: fixed;
top: 0;
right: -100%;
z-index: 1;
width: 100%;
height: 100%;
padding-top: 10rem;
background: #008880;
transition: all 400ms cubic-bezier(1.000, 0.000, 0.000, 1.000);
& ul{
& li a{
font-size: 2.5rem;
line-height: 3rem;
letter-spacing: .85rem;
color:#fff;
text-decoration: none;
text-align: center;
margin-bottom: 4rem;
}
}
}
.drawer-opened{
& .menu{
right: 0;
}
& #contents{
transform: translateX(-150px);
}
}
仕組みは基本と同じです。ハンバーガーボタンにはクリックされたら、activeというクラスが追加され、バッテンになるアニメーションの仕組みを書いています。またhoverやクリックなどの動作、変化前と変化後を滑らかにつなげるお手軽プロパティtransitionにてアニメーションを設定しています。簡単にアニメーションが滑らかに設定できる素晴らしいプロパティです。
※mainタグにも左150pxズレるだけで全体に動きが出て、おしゃれになります。
それではアニメーションを動かすトリガーはどのようなものか、下記がトリガーのエンジンとなります。
$(function(){
var body = $('body');
var hamburger = $('#hamburger');
hamburger.on('click', function() {
if(body.hasClass('drawer-opened')){
body.removeClass('drawer-opened');
$(this).removeClass('active');
} else {
body.addClass('drawer-opened');
$(this).addClass('active');
};
});
});
読んで字のごとくですね。上から下に処理が流れ真偽していきます。
・ハンバーガーボタンをクリックしたら
・bodyタグにdrawer-openedクラスがあるかないか確認
・あれば、bodyタグからdrawer-openedクラスを削除
・あれば、ハンバーガーボタンからactiveクラスを削除
・なければ、bodyタグにdrawer-openedクラスを追加
・なければ、ハンバーガーボタンにactiveクラスを追加
これで処理の出来上がりです。簡単でしかもJSライブラリだと行数もたった数行です。
ではjavaScriptでスクリプトを書くとどうなるのか確認してみましょう。
(function () {
const $body = document.querySelector('body');
const $hamburger = document.getElementById('hamburger');
$hamburger.addEventListener('click', function(){
$hamburger.classList.toggle('active')
});
$hamburger.addEventListener('click', navToggle);
function navToggle() {
if ($body.classList.contains('drawer-opened')) {
closeFunc();
} else {
openFunc();
}
}
function openFunc() {
$body.classList.add('drawer-opened');
}
function closeFunc() {
$body.classList.remove('drawer-opened');
}
})();
この程度のギミックなのでさほど差がでるわけではありませんが、JSライブラリと見比べると行数は増えていますね。
クラスがあるかないかはJSライブラリであればhasClassでしたが、JavaScriptではcontainsで有無のチェックをしています。この程度の行数でopenFuncやcloseFunc独自関数にまとめるほどではないですが、行数が増えた場合の見やすさと関数を分ける事でどのギミック用かわかるよう管理できますね。
いかがでしたでしょうか。今回はドロワーについてご紹介させていただきました。世の中で公開されているWEBサイトのアニメーションは、CSSにて構造し発動がJSというのが主流ではないかなと思います。またなんといっても、Vueなどフレームワークそれぞれにアニメーションのスクリプトはありますが、JavaScriptとCSSを使う事で効率よくアニメーションができ、追加などの管理がしやすいのではないかと私は思います。
以上となります。できる限りわかりやすく伝えようとしても書くのは難しいです。
コードや記事の書き方について気になるところがあれば、アドバイスいただけると嬉しいです。
要件定義からブラッシュアップ/実装運用まで一貫して担当。また内部対策を中心に、GTM・GA4・Looker Studioと分析・改善案の策定も進めています。北緯43度マルチエンジニア