先日、レスポンシブ対応のアコーディオンメニューの実装の依頼があり、思わぬところで躓いたので、備忘録として残しておきます。
jQueryを使用しますが、実装方法は簡単です。
サンプルは分かりやすくするために、余計な装飾は省いています。
あくまで構造だけ。
HTMLの「head」内に記述
1行目は、jqueryの読込です。
8~16行目までは、画面サイズに応じて、ul#menuの表示・非表示の切り替えをしています。
10行目の「var p = 480;」は横幅480pxになった時の、メニューの表示・非表示設定をしています。この記述があると、横幅を可変した時にメニューの切り替えがスムーズになります。
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js?ver=3.8.1"></script> <script type='text/javascript'> $(function(){ $("#toggle").click(function(){ $("#menu").slideToggle(); return false; }); $(window).resize(function(){ var win = $(window).width(); var p = 480; if(win > p){ $("#menu").show(); } else { $("#menu").hide(); } }); }); </script>
HTMLにメニュー部分を記述
<div id="nav"> <div id="toggle"> <a href="#">menu</a> </div> <ul id="menu"> <li><a href="#"><img src="sample.png" alt="" /></a></li> <li><a href="#"><img src="sample.png" alt="" /></a></li> <li><a href="#"><img src="sample.png" alt="" /></a></li> <li><a href="#"><img src="sample.png" alt="" /></a></li> <li><a href="#"><img src="sample.png" alt="" /></a></li> <li><a href="#"><img src="sample.png" alt="" /></a></li> </ul> </div>
id、class名などは適宜変更してください。
CSS記述。レスポンシブ記載あり。
/* ========================================================================== メニュー ========================================================================== */ div#nav{ margin: 100px 0; padding: 0; height: 40px; clear: both; } div#nav ul:after{ height: 0; visibility: hidden; display: block; font-size: 0; content: " "; clear: both; } div#nav ul li{ margin: 0; padding: 0 35px; float: left; /* メニュー横並び */ list-style-type: none; } div#nav ul li img{ height: auto; } #toggle{ display: none; } /* ========================================================================== 480px以下のデバイス向け設定 ========================================================================== */ /* 全体 */ @media only screen and (max-width: 480px) { body{ margin: 0; padding: 0; width: 480px; min-width: 480px; max-width: 480px; } div#nav{ margin: 0; width: 100%; } div#nav ul{ height: auto; display: none; text-align: center; } div#nav ul li{ margin: 10px auto; padding: 0; width: 480px; clear: left; } div#toggle{ margin: 100px auto 10px; width: 100%; display: block; } div#toggle a{ padding: 0; display: block; text-align: center; } div#nav ul li a:link, div#nav ul li a:visited{ display: block; } }
CSSは画像を使わないのであれば、もう少しシンプルに記述できます。
メニュースライドの表示速度を変更する
HTMLに組み込んだJSに直接書き込むだけ。
<script type='text/javascript'> $(function(){ $("#toggle").click(function(){ $("#menu").slideToggle(1000); return false; }); $(window).resize(function(){ var win = $(window).width(); var p = 480; if(win > p){ $("#menu").show(); } else { $("#menu").hide(); } }); }); </script>
4行目の「.slideToggle()」に数値を入れるか、「”fast”」「#normal”」「”slow”」を記述するだけ。
注意点
今回、陥ったミスは、メニューを画像にしたため、「height」で高さ指定をしたことでした。
別に高さ指定をしても動作には問題がないのですが、上下にスライドする時に表示速度が変わるように見え、一律の速さにしてほしいとの指摘を受けました。
レスポンシブ時にメニューの「ul」に「height:auto」を指定するだけのことなんですが、まさかこの記述だけで動作がおかしくなるとは思わず、かなり時間を使ってしまいました。
もしお困りの方がいらっしゃったら、お試しください。
@media only screen and (max-width: 480px) { div#nav ul{ height: auto; display: none; } }