position: sticky
は要素を配置する新しい方法であり、概念的には position: fixed
と似ています。違いは、position: sticky
を持つ要素は、ビューポートで特定のオフセットしきい値に達するまで、親内で position: relative
のように動作する点です。
ユースケース
Edward O’Connor によるこの機能の元の提案を要約:
スティッキー ポジショニングのご紹介
position: sticky
(ベンダー接頭辞付き)を追加するだけで、ユーザーがアイテム(またはその親)を上から 15 ピクセル上からスクロールするまで、要素を position: relative
にするよう指示できます。
.sticky {
position: -webkit-sticky;
position: -moz-sticky;
position: -ms-sticky;
position: -o-sticky;
top: 15px;
}
top: 15px
で、要素が固定されます。
この機能をわかりやすく説明するため、スクロール時にブログのタイトルを固定するデモを作成しました。
以前のアプローチ: スクロール イベント
これまで、スティッキー効果を実現するために、サイトでは JS で scroll
イベント リスナーが設定されていました。html5rocks のチュートリアルでも、この手法を使用しています。1, 200 ピクセル未満の画面では、一定時間スクロールすると、目次のサイドバーが position: fixed
に変わります。
以下は、ユーザーが下にスクロールするとビューポートの上部に固定され、ユーザーが上にスクロールすると元の位置に戻るヘッダーを作成する(今の古い方法)方法です。
<div class="header"></div>
<script>
var header = document.querySelector('.header');
var origOffsetY = header.offsetTop;
function onScroll(e) {
window.scrollY >= origOffsetY ? header.classList.add('sticky') :
header.classList.remove('sticky');
}
document.addEventListener('scroll', onScroll);
</script>
試してみる: http://output.jsbin.com/omanut/2/
これは簡単ですが、このモデルを多数の DOM ノードに対して行う場合(たとえば、ユーザーがスクロールするブログの <h1>
タイトルごとに行う場合)、
JS が理想的でない理由
一般に、スクロール ハンドラはおすすめしません。人々は作業量が多すぎることが多く、なぜ UI がジャンクになるのか疑問に思っています。
もう一つ考慮すべき点は、パフォーマンスを向上させるために、ハードウェア アクセラレーションによるスクロールを実装するブラウザが増えていることです。この問題は、JS のスクロール ハンドラが動作している際に、ブラウザが低速(ソフトウェア)モードにフォールバックすることが問題です。これで GPU が実行されなくなりました。そこで CPU に話を戻しますその結果、ユーザーがページのスクロール時にジャンクとして認識する。
そのため、このような機能を CSS で宣言的にする方が理にかなっています。
サポート
残念ながら、仕様はありません。6 月に www スタイルで提案され、つい最近 WebKit に導入されました。つまり、参照できる適切なドキュメントがないということです。ただし、このバグによると、left
と right
の両方を指定すると、left
が優先されます。同様に、top
と bottom
を同時に使用すると、top
が優先されます。
現時点でのサポートは、Chrome 23.0.1247.0 以降(現在の Canary 版)と WebKit ナイトリー版です。