解 説
サイドバーのあるホームページでは、ある程度スクロールした時点でサイドバーを画面上部などに固定表示させて見切れないようにする設定が有効です。さらにサイドバーの縦サイズが長い場合には、最後までスクロールした際にフッターにかぶらないよう、途中で固定を解除させる配慮が必要になります。今回は javascript とcssのposition:fixedを使い、サイドバーの固定と解除を行う方法をご紹介します。
1まずはhtmlを確認しましょう
ここはヘッダーです。
ここがメインエリア。 ※改行とかで適当に高さ調整してください。
2CSSでレイアウトを整えます
p{font-weight:bold;font-size:20px; color:#fff; padding:10px; line-height:1.5; margin:0;}
.header{width:1000px; margin:0 auto 30px;background:#666; padding:30px 0;}
.content_wrap{
width:1000px;
margin:0 auto 30px;
overflow:hidden;
}
.main_content{
width:720px;
float:left;
background:#aaa;
}
.sidebar{
width:260px;
float:right;
position:relative;
border-bottom:2px solid red;
}
.sidebar_inner{
width:260px;
background:#eee;
}
.sidebar p{
color:#333;
font-size:15px;
border:1px solid #ccc;
}
.footer{background:#444;padding:20px 0; height:600px;}
サイドバーの親要素(sidebar)に position:relative; を設定して起点を作っておきます。
3javascriptをこのように書けば完成です。
/*
<サイドバーの動き>
ページによってサイドバーの長さが異なってもOK。
メインのコンテンツより、サイドバーが短い場合に、サイドバーが最後まで行ったらそこで固定される。
加えて、ウィンドウよりもサイドバーが短い場合は、上に固定される。
*/
$(window).load(function () {
var w = $(window).width();
var x = 768; //768px以上(PC/タブレット)で発動
if (w >= x) {
//該当のセレクタなどを代入
var mainArea = $(".main_content"); /*メインコンテンツ*/
var sideWrap = $(".sidebar"); /*サイドバーの外枠*/
var sideArea = $(".sidebar_inner"); /*サイドバーの中身*/
var wd = $(window);
var mainH = mainArea.height();
var sideH = sideWrap.height();
if(sideH < mainH) { //メインの方が高ければ処理する
//サイドバーの外枠をメインと同じ高さにしてrelaltive指定(#sideをポジションで上や下に固定するため)
sideWrap.css({"height": mainH,"position": "relative"});
//サイドバーがウィンドウよりいくらはみ出してるか
var sideOver = wd.height()-sideArea.height();
//固定を開始する位置 = サイドバーの座標+はみ出す距離
var starPoint = sideArea.offset().top + (-sideOver);
//固定を解除する位置 = メインコンテンツの終点
var breakPoint = sideArea.offset().top + mainH;
wd.scroll(function() { //スクロール中の処理
if(wd.height() < sideArea.height()){ //サイドメニューが画面より大きい場合
if(starPoint < wd.scrollTop() && wd.scrollTop() + wd.height() < breakPoint){ //固定範囲内
sideArea.css({"position": "fixed", "bottom": "20px"});
}else if(wd.scrollTop() + wd.height() >= breakPoint){ //固定解除位置を超えた時
sideArea.css({"position": "absolute", "bottom": "0"});
} else { //その他、上に戻った時
sideArea.css("position", "static");
}
}else{ //サイドメニューが画面より小さい場合
var sideBtm = wd.scrollTop() + sideArea.height(); //サイドメニューの終点
if(mainArea.offset().top < wd.scrollTop() && sideBtm < breakPoint){ //固定範囲内
sideArea.css({"position": "fixed", "top": "20px"});
}else if(sideBtm >= breakPoint){ //固定解除位置を超えた時
//サイドバー固定場所(bottom指定すると不具合が出るのでtopからの固定位置を算出する)
var fixedSide = mainH - sideH;
sideArea.css({"position": "absolute", "top": fixedSide});
} else {
sideArea.css("position", "static");
}
}
});
}
}//PC/タブレットで発動のif
});
サイドバーがメインコンテンツよりも長い時 or 短い時の両方に対応できる便利なjavascriptです。

main_content と sidebar の2つのブロックをつくります。 sidebar の中にsidebar_inner (中身のボックス)をつくり、入れ子にしている点がポイントです。