一定範囲で position:fixed させる Ex Flex Fixed がかゆいとこだらけだったので作り直しました

かゆいとこだらけの Ex Flex Fixed (サイドメニューなどを一定の範囲でのみ position:fixed させる jQuery Ex Flex Fixed)を作り直しました。

改善内容

  • fixed 要素の幅を自動調整するようにした
  • リキッドレイアウト(可変幅)でちゃんと表示するようにした
  • fixed 要素がコンテナからはみ出ないようにした
  • fixed 要素がウィンドウ高さに収まらない状態でのスクロール時の表示を見やすくした
  • 動的にレイアウトサイズが変更されても、ちゃんと表示されるようにした
  • カラム高さを揃えるプラグインと併用できるようにした

という訳で半年も放置しておいてあれですが、ちょくちょく問い合わせもあるので、ご利用の際には新バージョンでどうぞ。

動作確認

以下のレイアウトのデモページで、新旧それぞれのバージョンの動作を確認してみます。

<div class="header"></div>
<div class="contents-wrapper">
	<div class="sub-contents-wrapper">
		<div class="sub-contents">
			sub contents
		</div>
	</div>
	<div class="main-contents-wrapper">
		<div class="main-contents">
			main contents
		</div>
	</div>
	<div class="ext-contents-wrapper">
		<div class="ext-contents">
			ext contents
		</div>
	</div>
</div>
<div class="footer"></div>
/* 全体をセンタリング */
body{
	margin :0 auto;
	max-width : 1000px;
	min-width : 600px;
}

/* clearfixでwrapperに高さを出す */
div.contents-wrapper{
	/zoom : 1;
}
div.contents-wrapper:after{
	content : '';
	display : block;
	clear : both;
}

/* subを固定幅 */
div.sub-contents-wrapper{
	margin-right : -200px;
	float : left;
	width : 200px;
	position : relative;
	z-index:1;
}
/* extを%指定可変幅 */
div.ext-contents-wrapper{
	margin-left : -30%;
	float : left;
	width : 30%;
	position : relative;
	z-index:1;
}
/* margin,padding,borderをつける */
div.sub-contents,
div.ext-contents{
	margin:16px;
	padding:8px;
	border:solid 4px #ccc;
}

/* メインコンテンツを可変幅 */
div.main-contents-wrapper{
	float : left;
	width:100%;
	position : relative;
}
div.main-contents{
	margin:16px;
	margin-left : 216px;
	margin-right : 31.5%;
	width : auto;
	padding:8px;
	border:solid 4px #ccc;
}

/* wpapper はblue系 */
div.contents-wrapper{
	background:#c0e0ff;
}
div.main-contents-wrapper{
	background:#b0d0ff;
}
div.sub-contents-wrapper,
div.ext-contents-wrapper{
	background:#a0c0f0;
}
/* contents はgray系 */
div.main-contents{
	background:#e8e8e8;
}
div.sub-contents,
div.ext-contents{
	background:#f0f0f0;
}

デモでは div.sub-contents、div.ext-contents を固定表示にします。

$('div.sub-contents,div.ext-contents').exFlexFixed({
	container : 'div.contents-wrapper'
});

デモ画面では、「Ex Flex Fixedを適用する」ボタンをクリックすると実行されます。

fixed 要素の幅を自動調整するようにした

通常 position:fixed を適用すると、内包物に合わせて幅が縮小しますが、position:static のように親要素に合わせた幅調整がされます。

Demo(旧) Demo(新)

任意の幅に固定したい場合は、width パラメータを指定します。

$('div.sub-contents,div.ext-contents').exFlexFixed({
	container : 'div.contents-wrapper',
	width : 80
});

リキッドレイアウト(可変幅)でちゃんと表示するようにした

旧バージョンでは、ウィンドウのリサイズで左カラムの表示位置がずれてしまいましたが、ずれないよう修正。


Demo(旧) Demo(新)

fixed 要素がコンテナからはみ出ないようにした

メインコンテンツの内容が少ないと、コンテナの高さがでず fixed 要素がはみ出してしまいましたが、はみ出さないよう修正。


Demo(旧) Demo(新)

fixed 要素がウィンドウ高さに収まらない状態でのスクロール時の表示を見やすくした

fixed 要素が大きくウィンドウ高さに収まらない状態でスクロールした場合、fixed 要素の全体を表示した後、位置固定をしますが、旧バージョンでは、上方向に向かってスクロールした場合、位置固定後のスクロールとなってしまい閲覧性がいまいちだったので修正。


Demo(旧) Demo(新)

上下にスクロールし、右カラムの表示のされ方を確認してください。

動的にレイアウトサイズが変更されても、ちゃんと表示されるようにした

旧バージョンでも(固定レイアウトに限り) watchPosition パラメータを指定する事で、ある程度対応できてましたが不完全でしたので修正。

$('div.sub-contents,div.ext-contents').exFlexFixed({
	container : 'div.contents-wrapper',
	watchPosition : true
});


Demo(旧) Demo(新)

ダミーテキストを、×で削除、+で追加することでレイアウトサイズを変更してみてください。

カラム高さを揃えるプラグインと併用できるようにした

Ex Equal Height という動的にレイアウトサイズが変更された場合でも、カラム高さを揃える事のできるプラグインを作りましたので、これを併用してみます。

$('div.contents-wrapper > div').exEqualHeight({
	watchHeight : true
});
$('div.sub-contents,div.ext-contents').exFlexFixed({
	container : 'div.contents-wrapper',
	watchPosition : true
});


Demo

exEqualHeight() メソッド実行時に、watchHeight パラメータを指定することで、動的なレイアウトサイズ変更にも対応させることができます。ただこの場合、内部的に setTimeout による監視が、exEqualHeight、exFlexFixed それぞれで行われることになるので、リソースや処理タイミングが気になる場合は、以下のような記述で調整処理をまとめることができます。

var height_API = $('div.contents-wrapper > div').exEqualHeight({
	api : true,
	watchHeight : false,
	windowResizeAdjust : false
});
$('div.sub-contents,div.ext-contents').exFlexFixed({
	container : 'div.contents-wrapper',
	watchPosition : true,
	watchCallback : function(fixed_API){
		height_API.adjust();
	}
});

Demo

exEqualHeight を非監視状態で実行、API オブジェクトを取得し、exFlexFixed の監視処理のコールバックにて、リサイズ判定+高さ調整を実行してます。

パラメータ

下記パラメータがあります。

api
初期値:false
true にすると api オブジェクトを返します。
watchPosition
初期値:'auto'
watchPosition パラメータ、windowResizeAdjust パラメータが共に auto の場合 false になります。true の場合、レイアウトの監視とサイズ・位置調整を行います。
watchDelay
初期値:500
指定値の間隔(ms)で監視処理を行います。
watchCallback
初期値:function(api){}
監視処理のコールバック関数を指定できます。apiapi オブジェクトが渡されます。
container
初期値:null
必須パラメータ。position:fixed 適用範囲となるコンテナ要素を指定します。
width
初期値:'auto'
position:fixed の幅を指定します。auto の場合は自動調整されます。
windowResizeAdjust
初期値:'auto'
watchPosition パラメータが true で且つ windowResizeAdjust パラメータが auto の場合 false になります。ウィンドウリサイズ時にサイズ・位置調整を行います。
windowResizeDelay
初期値:100
ウィンドウのリサイズイベントの発生判定間隔(ms)を指定します。

API

下記メソッドがあります。

adjustPosition()
レイアウトサイズ変更時に行われるサイズ・位置調整処理を行います。
adjustScrollPosition()
スクロール時に行われる位置調整処理を行います。

ダウンロード

こちらからどうぞ