【CSS】JS不要でピタッと固定!position: sticky;で作る見出し追従
Webサイトを作っていると、「スクロールしても特定の要素を画面内に残しておきたい(追従させたい)」という場面がよくあります。 昔からよく使われているのは position: fixed; ですが、最近のコーディングでは position: sticky; が大活躍しています!
「両方とも画面に固定するプロパティでしょ?何が違うの?」と疑問に思う方も多いはず。 今回は、よく使われる「セクション見出しの追従」のデモを通して、sticky の便利な動きと、fixed との決定的な違いを解説します!
デモ動作
See the Pen position: sticky; と fixed の違い by mikanbako (@mikanbako) on CodePen.
demo: position: sticky; で見出し追従
実装コード紹介
【HTML】
<div class="l-wrap">
<h2>position: sticky; デモ</h2>
<p class="p-desc">下にスクロールしてみてください。<br>各エリアの見出しが上部にピタッとくっつきます!</p>
<div class="p-demo-box">
<!-- エリア1 -->
<section class="p-section">
<h3 class="c-sticky-header">エリア 1 の見出し</h3>
<div class="p-section__content">
<p>エリア1に入りました!</p>
<p>見出し1が固定されます。</p>
<p>まだまだスクロールしてね!</p>
</div>
</section>
<!-- エリア2 -->
<section class="p-section p-section--bg2">
<h3 class="c-sticky-header">エリア 2 の見出し</h3>
<div class="p-section__content">
<p>エリア2に入りました!</p>
<p>見出し1が押し出されて、見出し2が固定されます。</p>
</div>
</section>
<!-- エリア3 -->
<section class="p-section p-section--bg3">
<h3 class="c-sticky-header">エリア 3 の見出し</h3>
<div class="p-section__content">
<p>エリア3に入りました!</p>
<p>見出し3が固定されます。</p>
<p>JSを使わなくても、CSSだけでこんな動きが作れます。</p>
</div>
</section>
<div class="c-spacer">スクロール用スペース</div>
</div>
</div>
<!-- fixed の例:トップへ戻るボタン -->
<button class="c-to-top js-to-top">Top</button>
【CSS】
/* ベース装飾 */
.l-wrap {
padding: 40px 20px;
max-width: 600px;
margin: 0 auto;
color: #3e3e3e;
}
h2 {
margin-bottom: 16px;
font-size: 16px;
color: #1bb4d4;
text-align: center;
}
.p-desc {
margin-bottom: 40px;
font-size: 16px;
font-weight: bold;
color: #666;
text-align: center;
line-height: 1.6;
}
/* スクロール用スペース */
.c-spacer {
height: 66vh;
display: flex;
justify-content: center;
align-items: center;
color: #888;
}
/* セクションの装飾(スクロールできるように高さを出す) */
.p-section {
margin-bottom: 20px;
background: #fff;
border: 2px solid #333;
border-radius: 8px;
}
.p-section--bg2 {
border-color: #e83e8c;
}
.p-section--bg3 {
border-color: #28a745;
}
.p-section__content {
min-height: 400px; /* スクロールさせるための高さ */
padding: 40px 20px;
font-size: 16px;
line-height: 1.6;
}
/* =========================================
💡 stickyの指定
========================================= */
.c-sticky-header {
position: sticky; /* これを指定するだけ! */
top: 0; /* 画面の上端(0px)に来たら固定する */
z-index: 10; /* テキストの上に重なるようにする */
padding: 15px;
/* 見出しの装飾 */
margin: 0;
font-size: 18px;
color: #fff;
background: #333;
}
.p-section--bg2 .c-sticky-header {
background: #e83e8c;
}
.p-section--bg3 .c-sticky-header {
background: #28a745;
}
/* =========================================
💡 fixedの指定(トップへ戻るボタン)
========================================= */
.c-to-top {
position: fixed; /* 画面に対して完全に固定! */
bottom: 20px; /* 下から20pxの位置 */
right: 20px; /* 右から20pxの位置 */
/* ボタンの装飾 */
display: flex;
justify-content: center;
align-items: center;
width: 40px;
height: 40px;
border-radius: 50%;
background: #1bb4d4;
color: #fff;
font-size: 12px;
font-weight: bold;
cursor: pointer;
box-shadow: 0 4px 10px rgba(0,0,0,0.2);
z-index: 100;
}
.c-to-top:hover {
opacity: 0.8;
}
【JavaScript】
/* =========================================
トップへ戻るボタンのスムーススクロール
========================================= */
const toTopBtn = document.querySelector('.js-to-top');
toTopBtn.addEventListener('click', () => {
window.scrollTo({
top: 0,
behavior: 'smooth' // スムーススクロールさせる
});
});
コードの解説と fixed との違い
sticky と fixed の決定的な違いは「親要素」!
/* =========================================
💡 stickyの指定
========================================= */
.c-sticky-header {
position: sticky; /* これを指定するだけ! */
top: 0; /* 画面の上端(0px)に来たら固定する */
...
デモをスクロールしてみてどうでしたか?見出しが画面上部に固定された後、次のセクションが来ると、古い見出しが上に押し出されて消えていったと思います。 これが、sticky の最大の特徴です!
❌ position: fixed; の場合
画面(ブラウザのウィンドウ)に対して完全に固定されます。
親要素の枠組みを完全に無視するため、ページの最後までずっとついてきます。
(※常に表示しておきたいグローバルナビゲーションや、画面右下のトップへ戻るボタンなどに適しています)
⭕️ position: sticky; の場合
「親要素の中でのみ」固定されます!
普段は普通の要素のように振る舞いますが、スクロールして指定した位置(top: 0 など)に到達すると画面に固定されます。そして、親要素の終わりが来ると、そこで追従をやめて一緒にスクロールされて消えていきます。
sticky を使う時の注意点
sticky が効かない!という時によくある原因が、
- 親要素(または先祖要素)に
overflow: hidden;がかかっている top: 0;などの位置設定がされていない
というパターンです。もし動かない時は、親要素のCSS設定を確認してみてください!
補足:公式ドキュメント
まとめ
今回は position: sticky; の便利な使い方と、fixed との違いについて解説しました。
position: fixed;は、画面全体に対して常に要素を固定したい時(トップへ戻るボタンや、固定ヘッダーなど)に使います。position: sticky;は、特定の親要素(セクションなど)の範囲内でのみ、スクロールに追従させたい時に使います。
昔はJavaScriptを使って複雑な計算をしないと実装できなかった「見出しの追従」が、今では sticky を使えばCSSたった数行で実装できてしまいます! ページ全体のパフォーマンス向上にも繋がるため、適材適所で使い分けて、モダンで快適なWebサイトを作っていきましょう!