golangの日記

Go言語を中心にプログラミングについてのブログ

CSSのposition:stickyの使い方

css.png


概要:

position:sticky を指定した要素の位置から親要素の高さや幅分、その要素を固定(fixed) できる。 JavaScript の scrollイベント を使って要素を固定するという動作を CSS で置き換えられる。





以下、画像は親要素(ピンクのボーダーのやつ) 内の sticky要素 (青いボーダーのやつ) の動作

position-sticky.gif



HTML

<body>
    <div class="sticky">Position sticky element</div>
</body>


CSS

body {
    height: 1000px; /* 親要素に高さをもたせる */ 
    padding-top: 200px;
}

.sticky {
    position: sticky;
    top: 0; /* 固定時の位置 */

    width: 80%;
    height: 40px;
    margin: 0 auto;
    border-radius: 20px;
    border: 10px solid skyblue;
    background-color: aquamarine;
}


position:stickyが効かない理由

  1. 親要素や先祖要素に overflow属性を指定していて、その値が visible 以外だった場合。
    overflowを指定していない場合(初期値)は visible なので特に overflow を設定していないのであれば関係ない。

  2. 親要素の高さ(height) が十分にない場合。
    親要素内でのみ固定されるので、高さが sticky 要素と同じかそれ以下であれば効果がない。



Firefox で JavaScript の scrollイベントを使って要素を固定すると以下のような警告がでる

const sticky = document.getElementsByClassName('sticky')[0];
const bcr = sticky.getBoundingClientRect();
addEventListener('scroll', e => {
    if (window.pageYOffset > bcr.top) {
        sticky.style.position = 'fixed';
        sticky.style.left = bcr.left + 'px';
        sticky.style.top = '0px';
    } else {
        sticky.removeAttribute('style');
    }
});


デベロッパーツールのコンソールに以下の警告がでる

このサイトはスクロールに対して配置を固定する効果が使用されています。
これは非同期パンで正しく動作しない可能性があります。
詳細は https://developer.mozilla.org/docs/Mozilla/Performance/ScrollLinkedEffects を参照し、
関連するツールと機能の議論に参加してください。