【2023年6月版】
position:sticky を攻略する
公開日: 2023/06/27
読了時間: 約 8分
本サイトでブログの目次に “position:sticky” 使ってますが、この調整に非常に苦労したのでメモを残しておきます。 ついでにここの表記では Tailwind CSS の表記を使用します。
“position:sticky” の独特さ
“sticky”の挙動わかりにくいです。見た目は非常にわかりやすいですが、どのように実現されているのか、HTML+CSSで実装してみると想像以上にわかりにくいです。 直感的にサイトの動きをイメージしてみるのと、HTML+CSSでそれを実現するのにはかなり乖離があります。
Tailwind CSS のリファレンスページには sticky
のサンプルがありますのでそちらでタグと挙動を確認してみてください。
それでは実装上でポイントとなる点をおさらいいたします。
ポイント1. 基本は “Relative”。だけど…
‘Sticky’ の基本となる動き、つまり”表示”位置の指定は “position: relative” と同じ挙動となります。 ところが ‘Sticky’ が発動する、つまりスクロールに対して固定となる挙動が開始する条件は、エレメントの元の位置が”スクロールの表示エリアの上辺にくっついたところ”となります。
top-8
などで縦位置を指定する前の、元々のY座標で判定されます。
挙動を見れば当たり前なのですが、実際にコーディングしていくとめっちゃ混乱してくるんすよ。。。
ポイント2. スクロールに対する ‘Sticky’ である。
わかってしまえば簡単なんですが、割と引っかかるのがここでして。 上記にも書いた通り、Stickyはスクロールに対する固定なので、Stickyの効果はスクロールしないエリアでは発動しません。。。 HTMLの記述になれる前はコンテンツが納まらないであっちこっちにスクロールバー出てきて困るんですが、HTMLに慣れてくるとコンテンツが枠に収まるように自然に組めますので、意識してわざわざスクロールするエリアを作り出さなければのはちょっとしんどいです。 頭の中のレイアウトとしては”この場所に固定しておいて~“となりますが、実装上はその上下、とくに下のエリアを特定の位置まで引き延ばして、そのブロックが画面に対してスクロールされるようにあえて組まないといけません。。
ポイント3. スクロールエリア上部との位置調整
ポイント1 でも上げましたが基本は relative と同じです。 発動するポイントは ‘top-0’ の位置で発生しますが、表示上の位置は ‘top-8’ などで調整します。 ここがスクロールエリア上部との”すき間” となります。
ポイント3. Sticky とその他のエレメント
Sticky はスクロールに対して固定され、それ以外のSticky ではないエレメントを通り過ぎるような挙動をします。 ここでStickyと同じように固定したいエレメントがある場合や、他のSticky なエレメントがある場合はちょっと考えなければなりません。
上記のポイント1で書いた通り、“スクロールの表示エリアの上辺にくっついたところ”からStickyが発動するので、同様に固定したいエレメントがある場合やStickyなエレメントはエリアの上部で重ならないように表示位置の調整が必要です。
Stickyさせたいエレメントが複数ある場合には、上記の Tailwind CSSのドキュメントにあるサンプルの挙動をみながらエレメントの構造を調整していく必要があります。
当サイトでの具体例
当サイトでは記事ページの”目次”を含む縦のエリアをスクロールエリアとして目次の部分ににStickyを仕込んでいます。 ↓こんな感じです。
で、HTMLはざっくり以下のような構造となっております。
<main ...>
<div class="relative flex flex-row items-stretch">
<article >
<!-- ブログ記事の本体-->
</article>
<aside>
<!-- 広告+目次エリア -->
<div class="h-80">
<!-- 高さ h-80 を確保して四角い広告エリア -->
</div>
<div class="sticky top-5">
<!-- 目次エリア -->
<!-- 続けて縦長の広告エリア -->
</div>
<aside>
</div>
</main>
このサイトでは目次の下に縦長の広告エリアを入れて、‘<aside>‘の縦方向の領域を確保し、スクロールを発生させています。 これがない場合は ‘h-full’ もしくは ‘my-0’ などで、高さを指定するか上下の余白をなくしてスクロールする領域を確保する必要があるでしょう。
また縦長の広告エリアを sticky
のエリアに含めているのは試行錯誤の結果です。
画面のスクロール時の挙動とHTMLを確認してみて下さい。
なかなか苦労させられました。。。
本日は以上といたします。