Unformed Building

スクロール途中から位置が固定されるナビゲーションを作ってみる

公開:
更新:

パーマリンク

ある程度スクロールすると、途中から位置が固定になるコンテンツを見かけたことはありませんか?
今回はjQueryを使ってそれを作ります。

デモ1
デモ2

途中から位置が固定されるナビゲーションのデモ 1 & 2 ダウンロード

今回使うHTMLはこんな感じです。

<div id="header">
  <h1>タイトル</h1>
</div>

<div id="container">
  <div id="main">左カラム(メインコンテンツ)</div>
  <div id="sidebar"><!-- サイドバー -->
    <div id="nav">ここを固定する</div>
  </div>
</div>

#main#sidebarfloat: leftしています。
これの#navが表示エリア上部から20pxの位置まで来たら位置を固定したいと思います。

position: fixedを使って固定する

デモ1をご覧ください。

ある程度スクロールしたら、#navfixedというクラス名をつけます。
CSSとJSは以下のようになります。

#sidebar {
  position: relative;
  float: left;
  width: 300px;
}

#nav {
  width: 300px;
  height: 300px;    /* デモ用 */
  background: #f88; /* 同上 */
}

.fixed {
  position: fixed;
  top: 20px;
}
var nav    = $('#nav'),
    offset = nav.offset();

$(window).scroll(function () {
  if($(window).scrollTop() > offset.top - 20) {
    nav.addClass('fixed');
  } else {
    nav.removeClass('fixed');
  }
});

スクロールするたびにtopの値を変更する

上記のコードですが、position: fixedはIE 6が対応していません。
その替わりとしてposition: relativeを使い、スクロールするたびにtopの値を変更して、位置を固定する方法を使ってみます。
デモ2をご覧ください。

CSSとJSは以下のようになります。

#sidebar {
  float: left;
  width: 300px;
}

#nav {
  position: relative;
  width: 300px;
  height: 300px;    /* デモ用 */
  background: #f88; /* 同上 */
}
var nav    = $('#nav'),
    offset = nav.offset();

$(window).scroll(function () {
  if($(window).scrollTop() > offset.top - 20) {
    nav.css('top', $(window).scrollTop() - offset.top + 20);
  } else {
    nav.css('top', 0)
  }
});

こっちの欠点は動きがぎこちないというか、ガタガタ動いてしまうことです。
使うときは上手いこと分岐させて、IE 6だけこっちを使うとかすればいいんじゃないでしょうか。