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/
これは簡単ですが、ユーザーがスクロールするたびにブログのすべての <h1>
タイトルなど、複数の DOM ノードでこれを行うと、このモデルはすぐに破綻します。
JavaScript が理想的でない理由
一般に、スクロール ハンドラはおすすめしません。ユーザーは、作業をやりすぎてしまい、UI がぎくしゃくする理由がわからない傾向があります。
ハードウェア アクセラレーションによるスクロールを実装してパフォーマンスを向上させるブラウザが増えていることも考慮してください。この場合の問題は、JS スクロール ハンドラが動作しているときに、ブラウザが低速の(ソフトウェア)モードにフォールバックする可能性があることです。これで、GPU で実行されなくなりました。代わりに、CPU に戻ります。その結果、ページをスクロールする際に、ユーザーがジャンクを感じます。
そのため、このような機能を CSS で宣言型にするのは理にかなっています。
サポート
残念ながら、この仕様はありません。これは 6 月に www-style で提案され、WebKit に実装されました。つまり、参照できる適切なドキュメントがないということです。ただし、このバグによると、left
と right
の両方が指定されている場合、left
が優先されます。同様に、top
と bottom
が同時に使用されている場合、top
が優先されます。
現在サポートされているのは、Chrome 23.0.1247.0 以降(現在の Canary)と WebKit ナイトリーです。