基本構造
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;
}



