基本構造
nav
の子要素にul
でマークアップします。
サブメニューはli
の子要素のさらに子要素にul
を入れ込みます。
HTML
<aside id="sidebar"> <h1 id="brand-logo">Logo</h1> <nav id="global-nav"> <ul> <li><a href="#">Home</a></li> <li class="sub-menu"> <a href="#">About</a> <ul class="sub-menu-nav"> <li><a href="#">About 1</a></li> <li><a href="#">About 2</a></li> <li><a href="#">About 3</a></li> </ul> </li> <li class="sub-menu"> <a href="#">Products</a> <ul class="sub-menu-nav"> <li><a href="#">Product 1</a></li> <li><a href="#">Product 2</a></li> <li><a href="#">Product 3</a></li> <li><a href="#">Product 4</a></li> </ul> </li> <li> <a href="#">Link</a> <ul class="sub-menu-nav"> <li><a href="#">Link 1</a></li> <li><a href="#">Link 2</a></li> <li><a href="#">Link 3</a></li> </ul> </li> <li><a href="#">Contact</a></li> </ul> </nav> </aside>
サイドバーはposition: fixed
で固定になります。
CSS
#sidebar { font-size: 15px; padding: 30px 0; width: 260px; height: 100%; position: fixed; color: #033560; background: #fff; text-align: center; }
アコーディオンの矢印マークは:after擬似要素で表示します。
is-active
のrotate
を変更することアコーディオン開閉時の矢印の向きを制御します。
is-active
クラスを切り替えはJavaScriptで行います。
CSS
#global-nav .sub-menu > a:after { content: ""; position: absolute; top: 0; bottom: 0; right: 18px; margin: auto; vertical-align: middle; width: 8px; height: 8px; border-top: 1px solid #033560; border-right: 1px solid #033560; transition: all .2s ease-out; transform: rotate(135deg); } #global-nav .sub-menu.is-active > a:after { transform: rotate(-45deg); }
シンプルなアコーディオンタイプ
クリックするとサブメニューがアコーディオンが開く、一番オーソドックスなタイプです。
アコーディオンはCSSでも頑張ればできますが、JSで書いた方がスマートですね。
jQueryのSlideでもいいですが、Velocity.jsというライブラリを使用することでスムーズにアニメーションできます。
is-active
クラスの切り替えは開いたときの矢印の切り替えに使っています。
JavaScript
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.0.0/velocity.min.js"></script> <script type="text/javascript"> (function($) { $(function () { $('.sub-menu > a').on('click', function (e) { e.preventDefault(); var $subNav = $(this).next('.sub-menu-nav'); if ($subNav.css("display") === "none") { $(this).addClass('is-active'); $subNav.velocity('slideDown', {duration: 400}); } else { $(this).removeClass('is-active'); $subNav.velocity('slideUp', {duration: 400}); } }); }); })(jQuery); </script>
センターでマウスオーバーアコーディオン
縦センターでマウスオーバーでアコーディオン開くようにするとダイナミックな動きになりますね。
#global-nav
にdisplay: flex
とalign-items: center;
で縦方向の中央揃えにできます。
CSS
#global-nav { text-align: center; height: 100%; display: -ms-flex; display: -webkit-flex; display: flex; -ms-flex-align: center; -webkit-align-items: center; align-items: center; }
JavaScript
$('.sub-menu').on({ 'mouseenter': function () { $(this) .addClass('is-active') .find('.sub-menu-nav').velocity('slideDown', { duration: 300 }); }, 'mouseleave': function () { $(this) .removeClass('is-active') .find('.sub-menu-nav').velocity('slideUp', { duration: 300 }); } });
マウスオーバーでサイドバーの横にスライドで開くタイプ
サブメニューの開閉自体はwdithをCSSのhoverで制御すればできますね。
サブメニューが開いているとき親のメニューもアクティブにするにはJavaScriptでクラスのON/OFFをします。
CSS
#global-nav .sub-menu-nav { position: fixed; background: #033560; color: #fff; top: 0; padding-top: 90px; left: 260px; width: 0; height: 100%; overflow: hidden; transition: width .2s ease-out; } #global-nav .sub-menu:hover .sub-menu-nav { width: 230px; }
クリックでスライドして切り替わるタイプ
サブメニューが子要素にあるとオーバーフローが上手くいかないので、このパターンだけHTMLの構造を変えています。
HTML
<aside id="sidebar"> <nav id="global-nav"> <ul> <li><a href="#">Home</a></li> <li class="sub-menu"><a href="#">About</a></li> <li class="sub-menu"><a href="#">Products</a></li> <li class="sub-menu"><a href="#">Link</a></li> <li><a href="#">Contact</a></li> </ul> </nav> <div id="sub-nav"> <div id="sub-nav2" class="sub-menu-nav"> <h3 class="sub-menu-head">About</h3> <ul> <li><a href="#">About 1</a></li> <li><a href="#">About 2</a></li> </ul> </div> <div id="sub-nav3" class="sub-menu-nav"> <h3 class="sub-menu-head">Products</h3> <ul> <li><a href="#">Product 1</a></li> <li><a href="#">Product 2</a></li> </ul> </div> <div id="sub-nav4" class="sub-menu-nav"> <h3 class="sub-menu-head">Link</h3> <ul> <li><a href="#">Link 1</a></li> <li><a href="#">Link 2</a></li> </ul> </div> </div> </aside>
JavaScriptではクリック時に#sidebar
にis-open-submenu
クラスを切り替えることでサブメニューの開閉を行います。
これだけだと全てのサブメニューが表示されてしまうので、表示するサブメニューはis-active
を付与します。
JavaScript
var $subNav = $('#sub-nav'); $('.sub-menu > a').on('click', function (e) { e.preventDefault(); var index = $(this).parent().index() + 1; $subNav.find('#sub-nav' + index).addClass('is-active'); $('#sidebar').addClass('is-open-submenu'); }); // サブメニューのタイトルをクリックすると閉じる $('.sub-menu-head').on('click', function () { $(this).parent().removeClass('is-active'); $('#sidebar').removeClass('is-open-submenu'); });
親の#sidebar
にoverflow: hidden
を指定します。
CSS
#sidebar { width: 260px; height: 100%; position: fixed; color: #fff; background: #033560; overflow: hidden; }
#global-nav
と.sub-menu-nav
をサブメニューが開いているときleft
それぞれ移動させます。
CSS
#global-nav { position: relative; left: 0; transition: left .3s linear; } .is-open-submenu #global-nav { left: -100px; } #sub-nav .sub-menu-nav { position: absolute; top: 0; left: 300px; width: 300px; height: 100%; z-index: 2; transition: left .3s linear; } #sub-nav .sub-menu-nav.is-active { left: 0; }