jQuery レスポンシブメニュープラグイン SlickNav の基本的な使い方や設定に関する個人的なメモ。マルチレベル(メニューの階層)にも対応しているので便利。
目次
SlickNav のページの「DOWNLOAD NOW」をクリックしてダウンロード。
解凍すると以下のようなファイルやフォルダがある。jQuery プラグイン SlickNav を使用するのに必要なファイルは「jquery.slicknav.min.js」と「slicknav.css」。これらのファイルを適当な場所に配置。
head 内で「slicknav.css」を読み込み。パスは環境(配置した場所)に合わせて変更。
以下はついでに「Modernizr」も読み込む場合。「Modernizr」はオプションで、必須ではない。
・・・ <title>タイトル</title> <link rel="stylesheet" href="css/slicknav.css" /> <script src="js/modernizr.custom.25639.js"></script> </head>
body の閉じタグの直前等で、「jQuery」と「jquery.slicknav.min.js」を読み込み。
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script src="js/jquery.slicknav.min.js"></script>
イージングを使用するには「jQuery UI」も読み込む必要がある。
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script> <script src="js/jquery.slicknav.js"></script>
マークアップは ul li 要素を使って記述。
ul 要素に任意の id を設定(以下の例では id=”menu”)。
<ul id="menu" class="clearfix"> <li><a href="#">Home</a></li> <li><a href="#">Works</a></li> <li><a href="#">Events</a></li> <li><a href="#">About</a></li> <li><a href="#">Contact</a></li> </ul>
メディアクエリを使って、表示・非表示を設定。
以下は、600px 未満では通常のメニュー(#menu)を非表示にし、SlickNav のメニュー(.slicknav_menu)を表示。
600px 以上では通常のメニューを表示して、 SlickNav のメニューを非表示にする例。
#menu { display: none; } @media screen and (min-width : 600px) { #menu { display: block; } .slicknav_menu { display: none; } }
以下は「Modernizr」を使って、JavaScript が有効になっている場合は「.js」が付くのでそれを利用する場合。
JavaScript が有効な場合で、600px 未満では通常のメニューを非表示にし、600px 以上では通常のメニューを表示して、 SlickNav のメニューを非表示にする例。
.js #menu { display: none; } @media screen and (min-width : 600px) { .js #menu { display: block; } .slicknav_menu { display: none; } }
関連ページ:ブラウザの HTML5, CSS3 の機能を検出してくれる Modernizr
任意の id を設定(以下の例では id=”menu”)した ul 要素を使って SlickNav をイニシャライズ。
<script> jQuery(function($){ $('#menu').slicknav(); }); </script>
基本的なサンプル(幅を狭くすると、SlickNav のメニューが表示される)
600px 未満の場合、SlickNav のメニューを表示する例。
HTML
<body> <div id="header"> <div id="header_inner"> <h1 id="logo">SlickNav Sample 1</h1> <img id="top_img" src="images/header.jpg" alt=""> </div> </div><!-- end of #header --> <div id="container"> <div id="navi"> <ul id="menu" class="clearfix"> <li><a href="#">Home</a></li> <li><a href="#">Works</a></li> <li><a href="#">Events</a></li> <li><a href="#">About</a></li> <li><a href="#">Contact</a></li> </ul> </div> <div id="content"> <h2>Contents</h2> ・・・ </div><!-- end of #content --> </div><!-- end of #container -->
CSS
#header { width: 100%; text-align: center; margin: 0 0 3px; position: relative; } #header_inner { max-width: 960px; min-width: 320px; margin: 0 auto; position: relative; } #container { max-width: 960px; min-width: 320px; margin: 0 auto; position: relative; } #content { width: 100%; position: relative; padding: 20px; } #navi { position: relative; margin: 1em 0; height: 20px; } #menu { display: block; height: auto; margin: 0; padding: 0; } #menu li { float: left; width: 20%; text-align: center; } #menu li a { padding: 0 20px 10px; border-top: none; border-right: none; background: none; color: #555555; display: inline-block; margin: auto; text-shadow: -1px 1px rgba(255, 255, 255, 0.8); } #menu li a:hover { background: none; color: #97C1F3; } #menu li a:active { color: #5687F8; } #menu { display: none; } @media screen and (min-width : 600px) { #content { margin: 0; } #menu { display: block; } .slicknav_menu { display: none; } }
SlickNav のオプションでは、「prependTo」を使ってメニューの表示位置を指定。
「prependTo」のデフォルトの値は「body」で、指定しない場合は一番上に表示される。
jQuery
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script src="js/jquery.slicknav.min.js"></script> <!--[if lt IE 9]> <script src="js/respond.min.js"></script> <![endif]--> <script> jQuery(function($){ $('#menu').slicknav({ prependTo:'#container' }); }); </script> </body>
サンプル2(幅を狭くすると、SlickNav のメニューが表示される)
ダウンロードした「slicknav.css」を編集することで、スタイルをカスタマイズすることが可能。
または、後から読み込む独自の CSS で値を上書きすることも可能。その場合「!important」を使用しないとうまくいかないみたい(?)。
またこの例では、サブメニューのあるマルチレベルのメニューを使用。
サブメニューにはクラス「sub-menu」を設定。
HTML
<body> <div id="header"> <div id="header_inner"> <h1 id="logo">SlickNav Sample 2</h1> <img id="top_img" src="images/header.jpg" alt=""> </div> </div> <div id="container"> <div id="navi"> <ul id="menu" class="clearfix"> <li><a href="#">Home</a></li> <li><a href="#">Works <i class="fa fa-caret-right"></i></a> <ul class="sub-menu"> <li> <a href="#">Painting</a> </li> <li> <a href="#">Drawing</a> </li> </ul> </li> <li><a href="#">Events</a></li> <li><a href="#">About</a></li> <li><a href="#">Contact</a></li> </ul> </div> <div id="content"> ・・・
CSS(ドロップダウンメニューのスタイリング等はかなりいい加減ですので参考にはならないと思う。)
#navi { position: relative; margin: 1em 0; height: 20px; } #menu { display: block; height: auto; margin: 0; padding: 0; } #menu li { float: left; width: 20%; text-align: center; position: relative; /*z-indexの指定や子要素の基準とするために指定*/ z-index: 1; /*ドロップダウンしたメニューが隠れないように*/ } #menu li a { padding: 0 20px 10px; border-top: none; border-right: none; background: none; color: #555555; display: inline-block; margin: auto; text-shadow: -1px 1px rgba(255, 255, 255, 0.8); } #menu li a:hover { background: none; color: #97C1F3; } #menu li a:active { color: #5687F8; } #menu li ul.sub-menu { display: none; /*サブメニューは最初は非表示にしておく*/ position: absolute; /*絶対配置にしておかないとうまくいかない*/ top: 2em; left: 30%; } #menu li:hover ul.sub-menu { display: block; /*マウスオーバー時にサブメニューを表示する*/ } #menu li ul.sub-menu li { float: none; /*サブメニューはフロートさせないので解除*/ } /*背景色などのカスタマイズ*/ .slicknav_nav li { border-top: 1px solid #3362B3; } .slicknav_menu { background-color: #1E1A42 !important; } .slicknav_menu .slicknav_icon-bar { background-color: #97C1F3 !important; } .slicknav_menu a:hover { color: #85A8FB !important; } .slicknav_btn { background-color: #1E1A42 !important; } .slicknav_nav .slicknav_row:hover { background: #1E1A42 !important; } .slicknav_nav a:hover { background: #1E1A42 !important; } i.fa { font-size: 18px; } i.fa.fa-caret-right { display: none; } #menu { display: none; } @media screen and (min-width : 600px) { body { margin: 0; } #content { margin: 0; } #menu { display: block; } .slicknav_menu { display: none; } i.fa.fa-caret-right { font-size: 14px; display: inline-block; } }
SlickNav のイニシャライズでは以下のオプションを設定。
マルチレベルのメニューでも、対応していてそのための設定は特になし。
jQuery
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> <script src="http://code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script> <script src="js/jquery.slicknav.js"></script> <script> jQuery(function($){ //ドロップダウンメニュー $('#navi ul>li').find('ul').hide(); $('#navi ul>li').hover(function(){ $('ul:not(:animated)', this).slideDown(700); }, function(){ $('ul',this).hide(); }); $('#menu').slicknav({ label: '', duration: 500, easingOpen: "easeOutBounce", //available with jQuery UI closedSymbol: '<i class="fa fa-angle-double-right"></i>', openedSymbol: '<i class="fa fa-angle-double-down"></i>', prependTo:'#container' }); }); </script>
サンプル3(幅を狭くすると、SlickNav のメニューが表示される)
メニューを上部に固定する例。
HTML はサンプル2と同じ。
CSS では以下のクラスを追加して、スクロールの位置により jQuery でこれらのクラスを追加・削除する。その他はサンプル2と同じ。
.slickmenuTop { display:block; position: fixed; width: 95%; top: 0; z-index: 100; } @media screen and (min-width : 600px) { #navi { z-index: 100; } .menuTop { background: #fff; border-bottom: 1px solid #ccc; -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); -moz-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); width: 100%; max-width: 960px; opacity: .90; } }
jQuery では、スクロールした際にメニューの位置を超えた場合は、メニューを上部に固定するように設定。
<script> jQuery(function($){ $('#navi ul>li').find('ul').hide(); $('#navi ul>li').hover(function(){ $('ul:not(:animated)', this).slideDown(400); }, function(){ $('ul',this).hide(); }); $('#menu').slicknav({ label: '', duration: 500, easingOpen: "easeOutBounce", //available with jQuery UI closedSymbol: '<i class="fa fa-angle-double-right"></i>', openedSymbol: '<i class="fa fa-angle-double-down"></i>', prependTo:'#container' }); var navi$ = $('#navi'); var navTop = navi$.offset().top; $(window).scroll(function () { var ww = $(window).width(); var winTop = $(this).scrollTop(); //ナビゲーションの固定 if(ww > 600) { if (winTop >= navTop) { navi$.css({position:'fixed', top: -12}).find('ul').addClass('menuTop').find('li').css('padding-top', '10px'); } else if (winTop <= navTop) { navi$.css({position:'relative', top: 0}).find('ul').removeClass('menuTop').find('li').css('padding-top', 0); } }else{ if (winTop >= navTop) { $('.slicknav_menu').addClass('slickmenuTop'); } else if (winTop <= navTop) { $('.slicknav_menu').removeClass('slickmenuTop'); } } }); }); </script>