可変幅+固定幅なマルチカラムレイアウトをレスポンシブにする jQuery Ex Responsive
なにやら意味の分かりづらいタイトルですが、「可変幅+固定幅なマルチカラムレイアウト」とは、ネガティブマージンを使って、メインコンテンツを可変幅、サイドバーを固定幅にするここのブログのようなレイアウトの事を指してます。詳しくは以下をご覧ください。
ただこのレイアウトの場合、いわゆるカラム落ちなどを利用した今はやりの(?)レスポンシブなレイアウトにすることができません・・・という訳で jQuery の力でこれを可能にするプラグインを作ってみました。
使い方
準備
jquery.exresponsive.css、jquery.js、jquery.exresponsive.js を読み込みます。
<link rel="stylesheet" type="text/css" media="screen" href="jquery.exresponsive.css"> <script type="text/javascript" src="../jquery.js"></script> <script type="text/javascript" src="../jquery.exresponsive.js"></script>
サンプルとして以下のような構成の HTML を使用します。
<div id="header"/> <div id="main-nav"/> <div id="main-contents"> <div id="image"/> <div id="image-info"/> </div> <div id="sub-nav"/> <div id="footer"/>
可変幅+固定幅の2カラムレイアウトにする(#main-contents + #sub-nav)
可変幅にしたい要素に対し、exResponsive() メソッドを実行します。固定幅にする要素はパラメータにて指定します。
// #main-contents を可変幅カラムに $('#main-contents').exResponsive({ fixTarget : 'next', // #sub-nav を固定幅カラムに fixAlign : 'right', // 固定幅カラムを右側に配置 fixWidth : 200, // 固定幅カラムを200pxに clearWidth : 416 // 可変幅カラムの幅が416px未満になったらカラム落ちさせる });
ここでは fixTarget パラメータに "next" を指定してるので、#main-contents の1つ後ろにいる #sub-nav を固定幅カラムにすることになります。(直感的じゃないんで、セレクタや要素自体の指定でも大丈夫なようにするかもしれません・・・)
- fixTarget
- "prev" 又は "next"(必須) 固定幅にする要素が、指定要素に対し前方(prev)にあるのか後方(next)にあるのかを指定します。
- fixAlign
- "left" 又は "right"(必須)
固定幅にする要素を、左(left)または右(right)に配置するかを指定します。 - fixWidth
- 固定幅にする要素の幅を指定します。(必須)
- clearWidth
- 可変幅の最少幅を指定します。ウィンドウをリサイズしこの値未満の幅なろうとすると float が解除されカラム落ちします。
可変幅カラム内の要素を横並びにする(#image + #image-info)
先の例同様、適用したい要素に exResponsive() メソッドを実行します。
// #image-info を可変幅カラムに $('#image-info').exResponsive({ fixTarget : 'prev', // #image を固定幅カラムにし fixAlign: 'left', // 左側に配置する fixWidth: 416, clearWidth : 230 });
固定幅+可変幅+固定幅の3カラムレイアウトにする(#main-nav + #main-contents + #sub-nav)
exResponsive() メソッドを実行すると、可変幅要素と固定幅要素を包むラッパー要素ができあがります。3カラムレイアウトにする場合は2回 exResponsive() メソッドを実行し、2回目の実行ではこのラッパー要素を指定します。
実行前 <div id="main-nav"/> <div id="main-contents"/> <div id="sub-nav"/> ↓ 1回目の実行(#main-contents + #sub-nav) <div id="main-nav"/> <div class="ex-responsive-wrap"> //ラッパー要素1 <div id="main-contents"/> <div id="sub-nav"/> </div> ↓ 2回目の実行(ラッパー要素1 + #main-nav) <div class="ex-responsive-wrap"> //ラッパー要素2 <div id="main-nav"/> <div class="ex-responsive-wrap"> //ラッパー要素1 <div id="main-contents"/> <div id="sub-nav"/> </div> </div>
// 1回目 // #main-contents を可変 $('#main-contents').exResponsive({ fixTarget : 'next', // #sub-nav を固定 fixAlign : 'right', fixWidth : 200, clearWidth : 420, callback : function(api){ // 2回目 // ラッパー要素を可変 api.getWrapper().exResponsive({ fixTarget : 'prev', //#main-nav を固定 fixAlign: 'left', fixWidth: 150, clearWidth : 870 }); } });
#main-contents への exResponsive() メソッドでできあがるラッパー要素が #main-nav の隣接要素となるので、これに対し exResponsive() メソッドを実行します。ラッパー要素は callback 処理にて渡される api オブジェクトの getWrapper() メソッドで取得できます。
api オブジェクトは callback を使用しなくても、api パラメータに true を指定することで取得することもできます。
var api = $('#main-contents').exResponsive({api : true, ... }); api.getWrapper().exResponsive({...
あるいは、data() メソッドでデータ名 "ex-responsive" を指定することでも取得できます。
$('#main-contents').exResponsive({...}); var api = $('#main-contents').data('ex-responsive'); api.getWrapper().exResponsive({...
CSS を適用してみる
exResponsive() メソッドを適用するとラッパー要素以外にも、レイアウト調整に必要となる要素が自動で生成されます。
適用前
<div id="main-contents"> ... </div> <div id="sub-nav"> ... </div>
適用後
<div class="ex-responsive-wrap"> //追加要素A(ラッパー要素) <div id="main-contents"> <div class="ex-responsive-auto-inner"> //追加要素B ... </div> </div> <div id="sub-nav"> <div class="ex-responsive-fix-inner"> //追加要素C ... </div> </div> </div>
autoClassName(可変幅のクラス名)、fixClassName(固定幅のクラス名) パラメータで、上記の追加要素B,Cに対しクラス名を割り当てることができます。
$('#main-contents').exResponsive({ autoClassName : 'main-contents', //#main-contents のクラス名 fixClassName : 'sub-nav', //#sub-nav のクラス名 fixTarget : 'next', fixAlign : 'right', fixWidth : 200, clearWidth : 420, callback : function(api){ api.getWrapper().exResponsive({ fixClassName : 'main-nav', //#main-nav のクラス名 fixTarget : 'prev', fixAlign: 'left', fixWidth: 150, clearWidth : 870 }); } });
また、追加要素B,Cについてはカラム落ちしてるか否かの判断が付くように、以下のようなクラス名が付加されます。
- カラム落ちしてる場合、クラス名 + "-off"
- カラム落ちしてない場合、クラス名 + "-on"
各カラムに背景色を付け、カラム落ちしてる場合のみリストを横並びにしてみます。
.main-contents{ background:#e8f0ff; } .main-nav{ background:#f0ffe8; } .sub-nav{ background:#f0e8f0; } .main-nav-off li{ float:left; width:100px; } .sub-nav-off li{ float:left; width:50%; }
コンテンツのラッパー要素を追加する
先のサンプルをみるとカラム内のコンテンツに余白(margin)が無いため見栄えがあまりよくありません。追加要素B、Cに margin を指定したいところですがこれらの要素は内部的にレイアウト調整で使用しており、へたに margin を設定してしまうと画面構成によってはレイアウトが崩れてしまいます。仕方がないのでカラム内コンテンツに対しさらにラッパー要素を追加し margin の調整をしてみます。
autoContentsClassName、fixContentsClassName パラメータを指定すると、指定した値をクラス名とするラッパー要素が追加要素B,C内に生成されます。
$('#main-contents').exResponsive({ autoContentsClassName : 'conntents-wrapper', //#main-contents のラッパー fixContentsClassName : 'conntents-wrapper', //#sub-nav のラッパー autoClassName : 'main-contents', fixClassName : 'sub-nav', fixTarget : 'next', fixAlign : 'right', fixWidth : 200, clearWidth : 420, callback : function(api){ api.getWrapper().exResponsive({ fixContentsClassName : 'conntents-wrapper', //#main-nav のラッパー fixClassName : 'main-nav', fixTarget : 'prev', fixAlign: 'left', fixWidth: 150, clearWidth : 870 }); } });
以下 CSS でカラム内コンテンツに margin を与えます。
.conntents-wrapper{ margin:16px; }
その他のパラメータ
- debug
- false(初期値) 又は true true にすると可変幅のサイズが表示されます。clearWidth パラメータの設定値を決める際に便利です。
その他の API メソッド
- on()
- clearWidth パラメータの設定に関わらず、マルチカラムレイアウトを有効にします。
- off()
- clearWidth パラメータの設定に関わらず、マルチカラムレイアウトを無効にします。
- adjust()
- clearWidth パラメータの設定を考慮し、マルチカラムレイアウトの有効化、無効化を行います。
動作確認
下記環境で動作確認をしてます。