【IE11対応】position sticky でスクロール中に固定表示する方法

スクロール量に応じて、要素を特定の位置に固定表示する方法をご紹介します。
数年前は、Javascriptを利用して、スクロールの量に応じてCSSのposition fixedを付け外しするような事をやっていましたが、position stickyを利用すると簡単に実装することが出来ます。

こちらにPosition Stickyのデモを作成しました。
メディアなどでよく見かけるような、スクロールしてもサイドバーが固定表示されるUIです。

position stickyとは

MDN Web Docs によると、下記のように説明されています。

包含ブロックがフロールート (又はその中でスクロールするコンテナー) 内の指定されたしきい値 (例えば top に設定された auto 以外の値など) を達するまでは相対的な配置として扱われ、包含ブロックの反対の端が来るまでその位置に「粘着」するものとして扱われます。

引用元: position – CSS: カスケーディングスタイルシート | MDN

ちょっとわかりづらいですが、position stickyを指定すると親のコンテナ要素(position relative)を基準にして、topで指定された位置までは通常の表示として扱われ、topで指定された位置から画面内に固定表示として扱われるようです。

スクロール量に応じて固定表示したいケースにドンピシャで利用できますね。
また、このように表示する要素のことを粘着位置指定要素というようです。

ブラウザサポート状況と不具合

position sticky ブラウザサポート状況

Can I Useでブラウザサポート状況について確認すると、上記のようになっています。
IEでサポートされていませんが、Polyfillを利用することでIEでも対応することが出来ます。

実装方法

実装方法は非常に簡単です。Position Stickyのデモをもとに説明します。
基本的には、粘着表示したい要素にposition stickytopを指定するのみです。

該当のソースは以下となります。

<div class="wrap">
    <main>メインコンテンツ</main>
    <aside>
        <section>サイドコンテンツ1</section>
        <section class="sticky">サイドコンテンツ2(固定)</section>
    </aside>
</div>
<style>
.wrap {
    display: flex;
    justify-content: space-between;
    width: 1000px;
    margin: auto;
    padding: 20px 0;
}
main {
    padding: 50px 0 800px;
    background: #EFEFEF;
    width: 720px;
    text-align: center;
}
aside {
    width: 260px;
}
aside section {
    background: #EFEFEF;
    padding: 100px 0;
    text-align: center;
}
aside section + section {
    position: sticky;
    top: 20px;
    margin-top: 20px;
}
</style>

今回は、サイドバーの一部のみを粘着表示したかったため、親のコンテナ要素であるasideの要素をmainを同等の高さにする必要があります。こちらについては、display flexによりmainasideの要素が同じ高さになっているため、main要素の下部まで粘着表示されることになります。

IE11の対応方法

残念ながら、position stickyはIE11では動作しません。IE11も対応する場合はPolyfillを利用すると良いと思います。

使い方は公式サイトにある通りで、以下のようになります。

  1. polyfillを読み込む
  2. stickyの要素に適用する

こちらのPosition Stickyのデモは、上記のpolyfillを利用してIE11に対応しています。

body最下部の部分がPolyfillを利用するためのコードです。

<script src="./stickyfill.min.js"></script>

<script>
    var elem = document.querySelectorAll('.sticky');
    Stickyfill.add(elem);
</script>

数行で対応できますので簡単ですね。ライブラリも6kbと軽量です。

さいごに

今まではこのようなスクロール量に応じて画面固定で表示したい場合は、

  • Javascriptを使用して指定の位置までスクロールしたらposition fixedをつける方法
  • スクロールが止まった時にフェードインさせる方法

などが用いられていたと思います。
※ Javascriptでスクロールイベントに合わせてtopを変更するようなことをすると表示がガタガタしてしまうので、スクロールが止まったらフェードインさせないといけないのです。。

これからは、position stickyを利用すれば、スクロール中の固定表示も簡単ですね。

  
● モダンなWebサイトの作り方を学びたい人のために

スタンダード・グリッド・シングルページレイアウトの作り方を学ぶことが出来ます。著者はグッドパッチ出身の吉田さん。