レスポンシブ対応でサイドメニューを一定範囲で固定表示する jQuery プラグイン

久しぶりのプログラム関連のエントリーです。
表題の「サイドメニューを一定範囲で固定表示」って意味通じますでしょうか? 画面スクロール時、サイドメニューが上部に流れきって消えてしまわないように途中から position:fixed で位置固定して、フッターにかぶる位置にきたら位置固定を解除するUIのことです。あの有名な LIG さんや痛いニュースでも採用されてるデザインです。
このちょくちょく見かけるUIのかゆいとこを解消した jQuery プラグインを紹介します。

一定範囲固定メニューのかゆいとこ

個人的意見ですが、よく見かける一定範囲固定メニューで感じるかゆいとこは以下2点です。

  1. レスポンシブに対応してない
  2. 上部方向にスクロールした場合、位置固定がなかなか解除されない

まず1の「レスポンシブに対応してない」についてですが、レスポンシブに対応してるやつを見たことがありません。実はスマホ持ってないんで個人的にはぜんぜん困らないんですが(笑)、新しくサイトデザインする際には一応、レスポンシブ意識するんで、その辺なんとかならんもんかなーって思っちゃいます。

あ、ちなみにここで言うレスポンシブに対応してない状態とは、以下のように画面幅を縮めてもシングルカラムレイアウトになることもなく、サイドメニューがサイドに配置されたままのことを言ってます。(LIGさんすいません、サンプルに使わせていただきました・・・Facebookでいっぱい友達になってくれたんで許してくれますよね ^^;)

LIG


次に2の「上部方向にスクロールした場合、位置固定がなかなか解除されない」についてですが、説明が難しいんでまず以下をご覧ください。

LIG

お分かりになりましたでしょうか?下部方向へのスクロール時は問題無いのですが、上部へスクロールしようとすると位置固定が解除されず、サイドメニュー上部のコンテンツになかなか辿りつけません。サイドメニューが充実したサイトでこれを見かけると若干残念な気持ちになります。


そんな訳でこれらかゆいとこを解決した jQuery プラグインを作ってみました。jQuery Sitekit の一機能として、もしくは単独の jQuery プラグインとして使用することができます。

一定範囲固定メニューのかゆいとこを解決した Fit Sidebar

jQuery、Fit Sidebar(または jQuery Sitekit)の JS/CSS ファイルを読み込みます。

  1. <link href="jquery.fit-sidebar.css" rel="stylesheet" type="text/css" media="screen" >
  2. <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
  3. <script src="jquery.fit-sidebar.js"></script>


マルチカラムレイアウトでマークアップします。

  1. <div class="page-header">header</div>
  2. <div class="page-body">
  3. <div class="main">
  4. <div class="contents"></div>
  5. </div>
  6. <div class="sub">
  7. <div class="contents"></div>
  8. </div>
  9. </div>
  10. <div class="page-footer">footer</div>

div.main にメインコンテンツ、div.sub にサイドメニューの記述を想定してます。


マルチカラムレイアウトになるよう CSS を定義します。

  1. /* 800px をブレークポイントに設定 */
  2. @media ( min-width : 800px ){
  3. .main{
  4. display:inline-block;
  5. vertical-align:top;
  6. width:75%;
  7. }
  8. .sub{
  9. display:inline-block;
  10. vertical-align:top;
  11. width:25%;
  12. }
  13. }

Media Queries を使用し、画面幅が 799px 以下になったらシングルカラムになるようにしてます。


サイドメニューに対し、fitSidebar() メソッドを実行します。

  1. $('div.sub div.contents').fitSidebar({
  2. wrapper : 'div.page-body',
  3. responsiveWidth : 800
  4. });

実行時 wrapper パラメータに、各カラムを包括するラッパー要素を指定します。ここでは div.page-body がそれに該当します。また、レスポンシブに対応させる場合は、responsiveWidth パラメータにブレークポイントとなる画面幅を指定します。

これでサイドメニューが一定範囲でのみ固定表示され、画面幅を縮めた場合シングルカラムに表示が切り替わるようになります。また、上部方向にスクロールした場合、サイドメニューの上端が見えるまで固定表示は行われません。

fit-sidebar


その他のパターン

メインカラムがサイドメニューのカラムより高さが無い場合、サイドメニューの固定表示は行われません。

両カラムに fitSidebar() メソッドを適用することで、高さのない方のカラムを固定表示にすることができます。

3カラム以上でも適用可能です。

パラメータ

プラグイン実行時、下記パラメータを指定できます。

  1. defaults : {
  2. wrapper : 'body', // 各カラムを包括する親又は先祖要素
  3. responsiveWidth : 0, // レスポンシブのブレークポイント
  4. fixedClassName : 'fit-sidebar-fixed-now', // 固定時に wrapperパラメータ指定要素に割り当てられるクラス名
  5. noFixedClassName : 'fit-sidebar-no-fixed-now' // 非固定時に wrapperパラメータ指定要素に割り当てられるクラス名
  6. },

ダウンロード

こちらからどうぞ

ちなみにだいぶ前にも似たようなプラグインを作ったことがあります。古いんでレスポンシブには対応してませんが、コードは冗長ですがこちらの方が高機能な部分もあるのでご参考までに・・・