CSSのposition: sticky;を徹底解説!スクロールで要素を固定・追従させる魔法の指定
Webサイトを閲覧していると、スクロールしてもヘッダーやサイドバーの一部が画面の決まった位置に固定されたまま追従してくるのを見たことはありませんか? これはユーザーの利便性を高める上で非常に有効なデザイン手法です。
この記事では、そんな便利な動きを実現するCSSのプロパティ、position: sticky;
について、その基本的な使い方から、よくある疑問、そして具体的な使用例まで、Web制作初心者の方にも分かりやすく徹底解説します。
position: sticky;
とは?
position: sticky;
は、CSSのposition
プロパティの一つで、要素がスクロール位置に応じて、通常の配置と固定された配置の間で切り替わる特性を持ちます。
まるで「粘着する」かのように、ある位置に達するまでは通常のコンテンツの流れの中にあり、指定した位置に達すると画面上の指定した位置に「ピタッと」固定され、スクロールに追従して表示されます。親要素の範囲を超えると、再び通常通りにスクロールされます。
よく似たプロパティにposition: fixed;
がありますが、これとの違いを簡単に見てみましょう。
position: fixed;
: 常にビューポート(ブラウザの表示領域)に固定されます。親要素や他の要素のスクロールには関係なく、常にその位置に居続けます。ヘッダーやフッター全体を固定する際によく使われます。position: sticky;
: 親要素の中でのみ有効です。親要素のスクロール領域内であれば固定され、親要素から外れると固定が解除されます。特定のセクションのタイトルやサイドバーの一部など、部分的に固定したい場合に非常に便利です。
position: sticky;
の基本的な使い方
position: sticky;
を使うには、CSSで以下の2つを指定することが必要です。
position: sticky;
top
,bottom
,left
,right
のいずれか、または複数
これらのオフセットプロパティ(top
など)は、「この要素がビューポートの端から何pxの位置に達したら固定を開始するか」を指定します。最もよく使われるのはtop: 0;
で、これは「要素が画面上部から0pxの位置に達したら固定する」という意味になります。
基本的なコード例
以下の例では、.sample-sticky-element
が親要素.sample-area
の中で、画面上部から0px
の位置に達すると固定されます。
See the Pen
Untitled by saku (@web-saku)
on CodePen.
HTML
<div class="sample-area"> <p>ここからスクロールすると、下の要素が固定されます。</p> <div class="sample-sticky-element"> 私はSticky要素です!スクロールすると固定されます。 </div> <div class="dummy-content"> <p>ここに長いコンテンツが入ります。</p> <p>スクロールして挙動を確認してください。</p> <p>親要素の範囲を超えると、私もスクロールします。</p> <p>...</p> <p>...</p> <p>...</p> <p>コンテンツの終わり。</p> </div> </div>
CSS
.sample-area { height: 600px; /* sticky要素の親要素に高さが必要です */ overflow-y: scroll; /* 親要素がスクロールを持つ場合 */ border: 1px dashed #ccc; padding: 10px; } .sample-sticky-element { position: sticky; top: 0; /* 画面の上部に達したら固定 */ background-color: #007bff; color: white; padding: 15px; text-align: center; font-weight: bold; } .dummy-content { height: 1000px; /* スクロールを発生させるためのダミーコンテンツ */ background-color: #f0f0f0; padding: 10px; margin-top: 20px; }
上記のサンプルで、.sample-sticky-element
が親要素.sample-area
のスクロール領域内でどのように固定されるかを確認してみてください。
なぜ動かない?sticky
が機能しない時のチェックポイント
「指定したのにposition: sticky;
が効かない!」という声はよく聞かれます。そんな時に確認すべきポイントをまとめました。
top
, bottom
, left
, right
の指定はありますか?
position: sticky;
単体では機能しません。必ずこれらのオフセットプロパティのいずれか(通常はtop
かbottom
)と組み合わせて指定してください。
CSS
/* OK */ .sticky-element { position: sticky; top: 0; } /* NG - これだけでは機能しません */ .sticky-element { position: sticky; }
親要素(または祖先要素)にoverflow
プロパティが設定されていませんか?
親要素や祖先要素にoverflow: hidden;
、overflow: scroll;
、overflow: auto;
などが設定されていると、sticky
が正常に機能しない場合があります。特にコンテンツが途中で隠れるようなoverflow
設定は注意が必要です。
親要素に十分な高さがありますか?
sticky
要素は「親要素の範囲内で」固定されます。もし親要素の高さがsticky
要素の高さと同じかそれよりも小さい場合、固定する余地がないためsticky
が機能しません。sticky
要素が固定されるべきスペースが親要素内に確保されているか確認しましょう。
例えば、フッターが親要素の場合、フッターの高さがsticky
要素の高さより小さいと、固定されずにすぐにフッターと一緒にスクロールアウトしてしまいます。
display: inline;
やfloat
、transform
、perspective
は使っていませんか?
以下のようなプロパティがsticky
要素自身、またはその親要素に設定されていると、sticky
の挙動に影響を与えることがあります。
display: inline;
: ブロック要素にしないと正しく機能しません。float
:float
が設定されている要素には適用されません。transform
、filter
、perspective
: これらのプロパティが親要素に設定されていると、sticky
要素がその親要素のスクロール領域として認識されなくなり、固定が解除されることがあります。
具体的な使用例
position: sticky;
は、Webサイトの様々な場所でユーザー体験を向上させるために活用できます。
ここからは具体的な使用例をいくつか紹介していきます。
1. ヘッダー/ナビゲーションの追従
最も一般的な使用例の一つです。ページをスクロールしても、サイトのヘッダーやナビゲーションメニューが常に画面上部に表示されることで、ユーザーはいつでも別のページに移動したり、サイト内の主要機能にアクセスしたりできます。
See the Pen
Untitled by saku (@web-saku)
on CodePen.
HTML
<header class="header-sticky" id="fixed-header"> <nav> <a href="#">ホーム</a> | <a href="#">製品</a> | <a href="#">お問い合わせ</a> </nav> </header> <div style="height: 1500px; background-color: #f8f9fa; padding: 20px;"> <p>ここに長いコンテンツが入ります。</p> <p>スクロールしてヘッダーが固定されるか確認してください。</p> <!-- 大量のダミーコンテンツ --> <p>...</p><p>...</p><p>...</p><p>...</p><p>...</p><p>...</p> <p>コンテンツの終わり。</p> </div>
CSS
.header-sticky { position: sticky; top: 0; /* 画面上部に固定 */ background-color: #343a40; color: white; padding: 15px 0; text-align: center; width: 100%; z-index: 1000; /* 他の要素の上に表示されるように */ } .header-sticky a { color: white; text-decoration: none; margin: 0 15px; }
2. サイドバー/目次の追従
ブログ記事やドキュメントサイトなどで、長いコンテンツを読んでいる途中で目次や関連情報が常に表示されるようにしたい場合に非常に役立ちます。ユーザーはスクロールすることなく、いつでも目次から別のセクションへジャンプできます。
See the Pen
Untitled by saku (@web-saku)
on CodePen.
HTML
<div class="main-content"> <div class="article-content"> <h2>記事のタイトル</h2> <p>記事の本文がここに続きます。非常に長いです。これは<code>sticky</code>サイドバーの親要素がスクロールを持つ例です。記事の内容が長くなると、サイドバーが固定されることで、ユーザーはいつでも目次を参照できます。</p> <h3>セクション1</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> <p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p> <h3>セクション2</h3> <p>Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit.</p> <p>Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus.</p> <h3>セクション3</h3> <p>At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident.</p> <p>Similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus.</p> <p>記事の終わり。</p> </div> <aside class="sidebar"> <div> <input type="search" placeholder="キーワードで検索"> </div> <div id="sticky-sidebar"> <h3>目次</h3> <ul> <li><a href="#">はじめに</a></li> <li><a href="#">使い方</a></li> <li><a href="#">注意点</a></li> <li><a href="#">使用例</a></li> <li><a href="#">まとめ</a></li> </ul> </div> </aside> </div>
CSS
.main-content { height: 900px; display: flex; gap: 20px; margin-top: 20px; margin-bottom: 30px; } .article-content { flex-grow: 1; background-color: #f0f2f5; padding: 20px; border-radius: 5px; height: 900px; /* スクロールを発生させるための高さ */ overflow-y: scroll; /* コンテンツがスクロールを持つ場合 */ } .sidebar div { width: 250px; margin-bottom: 20px; background-color: #e9ecef; padding: 20px; border-radius: 5px; flex-shrink: 0; align-self: flex-start; /* flexアイテムの配置 */ } #sticky-sidebar { position: sticky; top: 20px; /* 画面上部から20pxの位置で固定 */ }
3. テーブルのヘッダー行固定
データが大量にあるテーブルで、縦にスクロールしても常にヘッダー行(<th>
要素)が見えるようにしたい場合に非常に便利です。どの列が何のデータを示しているかを一目で確認できるため、データの比較や分析がしやすくなります。
See the Pen
Untitled by saku (@web-saku)
on CodePen.
HTML
<div class="table-wrapper"> <table> <thead> <tr> <th>ID</th> <th>商品名</th> <th>価格</th> <th>在庫</th> </tr> </thead> <tbody> <!-- 20行分のダミーデータ --> <tr><td>001</td><td>ノートPC</td><td>120,000円</td><td>15</td></tr> <tr><td>002</td><td>マウス</td><td>2,500円</td><td>50</td></tr> <tr><td>003</td><td>キーボード</td><td>8,000円</td><td>30</td></tr> <!-- ...さらに多くの行... --> <tr><td>020</td><td>ウェブカメラ</td><td>6,000円</td><td>25</td></tr> </tbody> </table> </div>
CSS
.table-wrapper { max-height: 300px; /* テーブルの高さ制限とスクロール */ overflow-y: auto; border: 1px solid #dee2e6; border-radius: 5px; } table { width: 100%; border-collapse: collapse; text-align: left; } th, td { padding: 10px; border-bottom: 1px solid #dee2e6; } th { background-color: #f8f9fa; font-weight: bold; } .table-wrapper thead th { position: sticky; top: 0; /* ヘッダー行を固定 */ background-color: #f8f9fa; /* 固定時に背景が透けないように */ z-index: 1; /* データの上に表示 */ }
まとめ
position: sticky;
は、CSSだけで手軽に要素をスクロールに追従させることができる非常に強力なプロパティです。以前はJavaScriptで実装する必要があった複雑なUI表現も、今ではCSSだけで実現できるようになりました。
ご紹介した「機能しない時のチェックポイント」を参考にしながら、ぜひご自身のWebサイトやポートフォリオでposition: sticky;
を活用してみてください。ユーザー体験が格段に向上するはずです!
このプロパティをマスターして、よりインタラクティブで使いやすいWebサイトをデザインしましょう!
[参考]
・position – CSS: カスケーディングスタイルシート | MDN > 粘着位置指定
関連記事
紙芝居のようにスクロールできる”StickyStack.js”の使い方
jQueryのプラグイン「StickyStack.js」の使い方を紹介します。スクロールした時にスタッキング要素が固定されて表示されるので、下からスクロールアップしてくる要素が上に重なっていくような視覚効果を実現することができます。
CSSでレスポンシブなtableをつくる
tableのレイアウトをパソコンでの表示とスマートフォンでの表示とで切り替えたい時など、ディスプレイの幅が違う時でもtableのレイアウトをCSSで適切に表示させたい時の方法を紹介します。
HTMLとCSSだけで作るタブ型のUI
Webページなどでよく見られるタブ型のUIを作る方法について紹介します。 タブ型のUIもいろいろな実装の方法があると思いますが、この記事内ではHTMLとCSSだけを使って設置する場合の方法についてお話ししてます。 HTMLとCSSによるタブ型UIの仕組みの紹介から作成の流れ、実装する際の記述例まで紹介しています。
HTMLのdetailsタグとsummaryタグで作るアコーディオン型UI
HTMLのdetailsタグとsummaryタグを利用してアコーディオン型のUIを作成する方法について紹介します。detailsタグとsummaryタグは比較的新しい要素なのでこれらのタグについての紹介から、これらの要素を使ってアコーディオンを作る方法、作成したアコーディオンをアレンジする方法まで紹介していきます。
HTML要素をCSSで中央寄せする3つの方法
今回はCSSのdisplay: grid;、display: flex;、position: absolute;の3つのプロパティを使ってHTML要素を中央に配置させる方法について紹介していきます。それぞれの方法ごとに画像を中央に配置する場合と、テキストを中央に配置する場合とについて例を挙げながら紹介していきます。
コメントを残す