CSSのstickyプロパティでWebサイトに固定要素を実装する方法

CSSのstickyプロパティでWebサイトに固定要素を実装する方法

公開: 更新:
CodeCampが提供するDX人材育成が可能なプログラミングやITが学べる公開講座

CSSのstickyプロパティは、スクロール時に要素を固定表示できる便利な機能です。ヘッダーやサイドバーを追従させたい場合、JavaScriptを使わずCSSだけで実装できるため、多くのWebサイトで活用されています。

しかし、position: fixed;との違いが分からない、実装しても効かない、といった悩みを抱えている方も多いと思います。stickyプロパティには特有の仕様があり、正しく理解しないと期待通りに動作しません。

この記事では、CSSのstickyプロパティの基本的な使い方から実装例、効かない場合の対処法、実際にコピペで使えるサンプルコードと共に詳しく解説していきます。



CSSのstickyプロパティとは

CSSのstickyプロパティは「positionプロパティの値の1つ」で、スクロール位置に応じて要素を固定表示できる機能です。通常時はrelativeと同じように配置され、スクロールによって指定位置に達すると、fixedのように固定される特性を持ちます。stickyプロパティを理解するには、以下の3つの概念を押さえる必要があります。

  • スティッキーアイテムの定義
  • スティッキーコンテナの定義
  • stickyとfixedの違い

それぞれの概念は、stickyプロパティの動作を正しく理解するために欠かせない要素で、特にスティッキーコンテナの範囲を把握することが実装の鍵となります。これらを理解することで、なぜstickyが効かないのか、どのような場合に使うべきか、などが明確になるでしょう。

それでは各項目について、詳しく解説していきます。

スティッキーアイテムの定義

スティッキーアイテムとは、position: sticky;が指定された要素そのものを指します。通常時は親要素内で通常のフローに従って配置され、スクロールによって指定位置に達すると固定表示に切り替わります。

<!DOCTYPE html>
<html>
<head>
  <style>
    .sticky-item {
      position: sticky;
      top: 20px;
      background-color: #ffeb3b;
      padding: 10px;
      margin: 10px 0;
    }
    .normal-item {
      background-color: #e0e0e0;
      padding: 10px;
      margin: 10px 0;
    }
  </style>
</head>
<body>
  <div class="normal-item">通常の要素1</div>
  <div class="sticky-item">スティッキーアイテム</div>
  <div class="normal-item">通常の要素2</div>
  <div class="normal-item">通常の要素3</div>
</body>
</html>

上記のコードで、.sticky-itemクラスを持つ要素がスティッキーアイテムです。スクロール前は通常の要素と同じように配置されますが、上から20pxの位置に達すると固定され、それ以降はスクロールしても画面上部から20pxの位置に表示され続けます。スティッキーアイテムは複数配置でき、それぞれ独立して動作します。

スティッキーコンテナの定義

スティッキーコンテナとは、スティッキーアイテムの親要素のことを指します。スティッキーアイテムは、このコンテナの範囲内でのみ固定表示され、コンテナの終端に達すると固定が解除され一緒にスクロールアウトします。

<!DOCTYPE html>
<html>
<head>
  <style>
    .sticky-container {
      background-color: #f5f5f5;
      padding: 20px;
      margin: 20px 0;
      height: 500px;
    }
    .sticky-item {
      position: sticky;
      top: 0;
      background-color: #2196f3;
      color: white;
      padding: 10px;
    }
  </style>
</head>
<body>
  <div class="sticky-container">
    <div class="sticky-item">固定される要素</div>
    <p>コンテナ内のコンテンツ</p>
  </div>
  <div style="height: 1000px;">コンテナ外のコンテンツ</div>
</body>
</html>

上記のコードでは、.sticky-containerクラスがスティッキーコンテナです。スティッキーアイテムは、このコンテナの範囲内でのみ固定され、コンテナの下端に達すると固定が解除されます。コンテナの高さが不足している場合、スティッキーアイテムは固定されず通常の要素と同じ動きになるため、コンテナには十分な高さを確保する必要があります。

stickyとfixedの違い

stickyとfixedは、どちらも要素を固定表示できるプロパティですが、動作の仕組みが大きく異なります。fixedは常に画面(ビューポート)に対して固定され、親要素の範囲に関係なく表示され続けますが、stickyは親要素(スティッキーコンテナ)の範囲内でのみ固定されます。

stickyとfixedの主な違いは、以下の通りです。

項目 sticky fixed
固定の範囲 親要素の範囲内のみ ビューポート全体
通常時の配置 通常フローに従う 通常フローから除外
要素の高さ 元の位置に高さを保持 高さを保持しない
スクロール追従 条件付きで追従 常に追従

fixedを使用すると、要素が通常のフローから除外されるため、後続の要素が上に詰まってレイアウトが崩れる可能性があります。一方、stickyは通常時に要素の高さを保持するため、レイアウトへの影響が少ないです。ヘッダーやサイドバーを固定する場合、ページ全体で常に表示したいならfixed、特定のセクション内でのみ固定したいならstickyを選択すると良いでしょう。

CSSのstickyプロパティで要素を固定する方法

CSSのstickyプロパティで要素を固定するには、以下3つの方法があります。

  • top/bottomプロパティで固定位置を指定する
  • left/rightプロパティで横方向の固定位置を指定する
  • z-indexで重なり順を制御する

それぞれの方法は、固定する方向や重なりの制御によって使い分ける必要があり、適切に組み合わせることで柔軟な実装ができます。それでは各項目について、詳しく解説していきます。

【PR】プログラミングや生成AIを無料で学べる「コードキャンプフリー」

top/bottomプロパティで固定位置を指定する

top/bottomプロパティは、縦方向のスクロール時に要素を固定する位置を指定します。topは画面上部からの距離、bottomは画面下部からの距離を設定するプロパティです。どちらか一方を指定することによって、要素が固定される位置が決まります。

top/bottomプロパティを使った基本的なコードは、以下の通りです。

<!DOCTYPE html>
<html>
<head>
  <style>
    .sticky-header {
      position: sticky;
      top: 0;
      background-color: #333;
      color: white;
      padding: 10px;
    }
    .content {
      height: 2000px;
    }
  </style>
</head>
<body>
  <div class="sticky-header">固定されるヘッダー</div>
  <div class="content">スクロール可能なコンテンツ</div>
</body>
</html>

上記のコードでは、.sticky-headerクラスにposition: sticky;とtop: 0;を指定しています。この設定により、ヘッダーが画面最上部に到達した時点で固定され、それ以降はスクロールしても画面上部に表示され続けます。bottomプロパティを使用する場合は、top: 0;の代わりにbottom: 0;と記述することで、画面下部に固定できます。

left/rightプロパティで横方向の固定位置を指定する

left/rightプロパティは、横方向のスクロール時に要素を固定する位置を指定します。leftは画面左端からの距離、rightは画面右端からの距離を設定するプロパティで、横スクロールが発生するレイアウトで要素を固定したい場合に使用します。

left/rightプロパティを使った基本的なコードは、以下の通りです。

<!DOCTYPE html>
<html>
<head>
  <style>
    .container {
      width: 2000px;
      overflow-x: auto;
    }
    .sticky-column {
      position: sticky;
      left: 0;
      background-color: #f0f0f0;
      width: 150px;
      display: inline-block;
    }
    .content-column {
      display: inline-block;
      width: 300px;
    }
  </style>
</head>
<body>
  <div class="container">
    <div class="sticky-column">固定される列</div>
    <div class="content-column">スクロール可能な列1</div>
    <div class="content-column">スクロール可能な列2</div>
    <div class="content-column">スクロール可能な列3</div>
  </div>
</body>
</html>

上記のコードでは、.sticky-columnクラスにposition: sticky;とleft: 0;を指定しています。この設定により、横スクロールが発生しても最初の列が画面左端に固定され、テーブルの行ヘッダーのような表現が可能です。rightプロパティを使用する場合は、left: 0;の代わりにright: 0;と記述することで、画面右端に固定できます。

z-indexで重なり順を制御する

z-indexプロパティは、sticky要素が他の要素と重なった際の表示順序を制御します。z-indexとは、要素の重なり順を数値で指定するプロパティのことで、値が大きいほど手前に表示されます。

z-indexプロパティを使った基本的なコードは、以下の通りです。

<!DOCTYPE html>
<html>
<head>
  <style>
    .sticky-header {
      position: sticky;
      top: 0;
      background-color: #333;
      color: white;
      padding: 10px;
      z-index: 100;
    }
    .content-box {
      position: relative;
      background-color: #e0e0e0;
      margin: 20px 0;
      padding: 20px;
      z-index: 1;
    }
  </style>
</head>
<body>
  <div class="sticky-header">固定ヘッダー</div>
  <div class="content-box">コンテンツ1</div>
  <div class="content-box">コンテンツ2</div>
  <div class="content-box">コンテンツ3</div>
</body>
</html>

上記のコードでは、.sticky-headerクラスにz-index: 100;を指定しています。この設定により、ヘッダーがスクロールでコンテンツと重なった際に、常に最前面に表示されます。

z-indexを指定しない場合、HTML上で後に記述された要素が手前に表示されるため、sticky要素が隠れてしまう可能性があります。複数のsticky要素を配置する場合は、それぞれに適切なz-index値を設定することが重要です。

CSSのstickyプロパティを使った実装例

CSSのstickyプロパティは、ヘッダーやサイドバーなど様々な箇所で活用できます。実際のWebサイトでよく使われる実装パターンとして、以下の4つがあります。

  • ヘッダーを固定する
  • サイドバーを固定する
  • テーブルヘッダーを固定する
  • フッターを固定する

それぞれの実装例は、使用する場面や目的によって適したパターンが異なり、ユーザビリティの向上に貢献します。特にヘッダーとサイドバーの固定は多くのWebサイトで採用されており、ナビゲーションの利便性を高める効果があります。

それでは各項目について、詳しく解説していきます。

ヘッダーを固定する

ヘッダーを固定することで、ユーザーがページのどこにいても、ナビゲーションにアクセスできるようになります。stickyプロパティを使用すると、ページ上部に到達したタイミングでヘッダーが固定され、スクロールしても常に表示され続けます。

<!DOCTYPE html>
<html>
<head>
  <style>
    header {
      position: sticky;
      top: 0;
      background-color: #2c3e50;
      color: white;
      padding: 15px;
      z-index: 1000;
    }
    nav ul {
      list-style: none;
      margin: 0;
      padding: 0;
      display: flex;
      gap: 20px;
    }
    nav a {
      color: white;
      text-decoration: none;
    }
    .content {
      height: 2000px;
      padding: 20px;
    }
  </style>
</head>
<body>
  <header>
    <nav>
      <ul>
        <li><a href="#">ホーム</a></li>
        <li><a href="#">サービス</a></li>
        <li><a href="#">お問い合わせ</a></li>
      </ul>
    </nav>
  </header>
  <div class="content">
    <h1>メインコンテンツ</h1>
    <p>ここにコンテンツが入ります</p>
  </div>
</body>
</html>

上記のコードでは、headerタグにposition: sticky;とtop: 0;を指定しています。z-index: 1000;を設定することで、他の要素と重なった際にヘッダーが最前面に表示されます。ヘッダーの固定は、特に縦長のページで効果を発揮し、ユーザーがスクロールしてもすぐにナビゲーションにアクセスできるため、利便性が大幅に向上します。

サイドバーを固定する

サイドバーを固定することで、メインコンテンツをスクロールしても、サイドバーの情報を常に表示できます。2カラムレイアウトでサイドバーに「ナビゲーション」や「関連情報」を配置している場合に有効な実装です。

<!DOCTYPE html>
<html>
<head>
  <style>
    .container {
      display: flex;
      gap: 20px;
      max-width: 1200px;
      margin: 0 auto;
    }
    .sidebar {
      width: 250px;
    }
    .sidebar-inner {
      position: sticky;
      top: 20px;
      background-color: #f5f5f5;
      padding: 20px;
      border-radius: 5px;
    }
    .main-content {
      flex: 1;
      padding: 20px;
    }
    .content-block {
      height: 500px;
      background-color: #e0e0e0;
      margin-bottom: 20px;
      padding: 20px;
    }
  </style>
</head>
<body>
  <div class="container">
    <aside class="sidebar">
      <div class="sidebar-inner">
        <h3>目次</h3>
        <ul>
          <li><a href="#">セクション1</a></li>
          <li><a href="#">セクション2</a></li>
          <li><a href="#">セクション3</a></li>
        </ul>
      </div>
    </aside>
    <main class="main-content">
      <div class="content-block">コンテンツ1</div>
      <div class="content-block">コンテンツ2</div>
      <div class="content-block">コンテンツ3</div>
    </main>
  </div>
</body>
</html>

上記のコードでは、.sidebar-innerクラスにposition: sticky;とtop: 20px;を指定しています。サイドバー自体ではなく、サイドバー内部の要素にstickyを適用することで、柔軟な固定が可能です。この実装により、メインコンテンツが長い場合でも、サイドバーの目次やナビゲーションが常に表示され、ユーザーが記事内を移動しやすくなります。

【PR】『Python』を学べる企業・個人向けのプログラミングコース

テーブルヘッダーを固定する

テーブルヘッダーを固定することで、縦に長いデータテーブルをスクロールしても、列の見出しが常に表示されます。データの内容と列名を対応させやすくなるため、可読性が大幅に向上します。

<!DOCTYPE html>
<html>
<head>
  <style>
    table {
      width: 100%;
      border-collapse: collapse;
    }
    thead th {
      position: sticky;
      top: 0;
      background-color: #4caf50;
      color: white;
      padding: 12px;
      text-align: left;
      z-index: 10;
    }
    tbody td {
      padding: 12px;
      border-bottom: 1px solid #ddd;
    }
    tbody tr:hover {
      background-color: #f5f5f5;
    }
  </style>
</head>
<body>
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>名前</th>
        <th>年齢</th>
        <th>職業</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>1</td>
        <td>山田太郎</td>
        <td>30</td>
        <td>エンジニア</td>
      </tr>
      <tr>
        <td>2</td>
        <td>佐藤花子</td>
        <td>28</td>
        <td>デザイナー</td>
      </tr>
      <!-- さらに多くの行が続く -->
    </tbody>
  </table>
</body>
</html>

上記のコードでは、thead thセレクタにposition: sticky;とtop: 0;を指定しています。z-index: 10;を設定することで、テーブルの行データと重なった際にヘッダーが上に表示されます。この実装により、データ量が多いテーブルでも、ユーザーがスクロールしながら各列が何を表しているか常に確認でき、データの比較や分析がしやすくなります。

フッターを固定する

フッターを固定することで、ページの下部に到達する前からフッター情報を表示できます。bottomプロパティを使用することによって、画面下部からの距離を指定し、スクロール時にフッターを固定表示します。

<!DOCTYPE html>
<html>
<head>
  <style>
    body {
      margin: 0;
      font-family: Arial, sans-serif;
    }
    .content {
      height: 2000px;
      padding: 20px;
    }
    footer {
      position: sticky;
      bottom: 0;
      background-color: #333;
      color: white;
      padding: 15px;
      text-align: center;
      z-index: 100;
    }
  </style>
</head>
<body>
  <div class="content">
    <h1>メインコンテンツ</h1>
    <p>ここにコンテンツが入ります</p>
  </div>
  <footer>
    <p>© 2024 Your Website. All rights reserved.</p>
  </footer>
</body>
</html>

上記のコードでは、footerタグにposition: sticky;とbottom: 0;を指定しています。この設定により、ページを上にスクロールしてフッターが画面下部に達すると、フッターが固定表示されます。フッターの固定は、著作権表示や重要なリンクを常に表示したい場合に有効で、ユーザーがページのどこにいても必要な情報にアクセスできます。

CSSのstickyプロパティが効かない原因と対処法

CSSのstickyプロパティを実装しても、期待通りに動作しないケースがあります。正しく設定しているつもりでも効かない場合、以下3つの原因が考えられます。

  • 親要素にoverflowが指定されている
  • topなどの位置指定がない
  • 親要素の高さが不足している

それぞれの原因は、stickyプロパティの仕様に関係しており、1つでも該当すると正常に動作しません。特にoverflowプロパティの指定は見落としやすく、CSSのリセットフレームワークで意図せず設定されている場合もあります。

それでは各項目について、詳しく解説していきます。

親要素にoverflowが指定されている

親要素にoverflow: hidden;、overflow: auto;、overflow: scroll;のいずれかが指定されていると、stickyプロパティは動作しません。overflowプロパティとは、要素からはみ出したコンテンツの表示方法を制御するプロパティのことで、これが指定されているとスティッキーコンテナの範囲が制限されてしまいます。

対処法としては、以下の通りです。

  • 親要素のoverflowプロパティをvisible(初期値)に変更する
  • overflowが必要な場合は、さらに外側の要素に移動する
  • sticky要素の階層構造を見直し、overflow指定がない親要素配下に配置する

親要素のoverflowを削除または変更できない場合は、HTML構造を見直す必要があります。sticky要素とoverflow指定された要素の間に、別の要素を挟むことで解決できる場合もあるため、階層構造を工夫してください。

topなどの位置指定がない

position: sticky;を指定しただけでは、要素は固定されません。top、bottom、left、rightのいずれか1つ以上を指定することによって、どの位置で固定するかを明示する必要があります。

対処法は、以下の通りです。

  • 縦方向に固定する場合は、topまたはbottomを指定する
  • 横方向に固定する場合は、leftまたはrightを指定する
  • 値には0やpx単位の数値を設定する

位置指定がない場合、ブラウザは要素をどこで固定すべきか判断できないため、通常のrelativeと同じ動作になります。最も一般的な指定はtop: 0;で、画面最上部に要素を固定できます。bottomやleft、rightを使う場合も、同様に具体的な値を指定してください。

親要素の高さが不足している

スティッキーコンテナ(親要素)の高さが、スティッキーアイテムの高さと同じかそれ以下の場合、stickyは動作しません。stickyプロパティは親要素の範囲内でのみ固定されるため、親要素に十分な高さがないと固定される余地がないからです。

対処法は、以下の通りです。

  • 親要素に明示的な高さを設定する
  • 親要素内に十分なコンテンツを配置して高さを確保する
  • min-heightプロパティで最小高さを保証する

親要素の高さはスティッキーアイテムの高さに加えて、固定表示させたい距離分の高さが必要です。例えば、高さ100pxの要素を200pxスクロール中に固定表示させたい場合、親要素には最低300px以上の高さが必要になります。親要素の高さが不足していないか、開発者ツールで確認すると良いでしょう。

※上記コンテンツの内容やソースコードはAIで確認・デバッグしておりますが、間違いやエラー、脆弱性などがある場合は、コメントよりご報告いただけますと幸いです。

ITやプログラミングに関するコラム


ITやプログラミングに関するニュース

ブログに戻る

コメントを残す

コメントは公開前に承認される必要があることにご注意ください。

CodeCampが提供するDX人材育成が可能なプログラミングやITが学べる公開講座 - IT・プログラミングを知って学べるコネクトメディア コードキャンプが提供する無料で学べるプログラミングスクール講座 - IT・プログラミングを知って学べるコネクトメディア コードキャンプDX人材育成研修 - IT・プログラミングを知って学べるコネクトメディア 配属3ヶ月で30%の生産性向上を実現するいよぎんコンピュータサービスの新人研修に迫る - IT・プログラミングを知って学べるコネクトメディア 金融業界の業務効率化を加速するニッセイアセットマネジメントの生成AI×GAS活用研修事例 - IT・プログラミングを知って学べるコネクトメディア 【製造業のDX人材育成事例】デジタル人材の即戦力化を実現する、日本ガイシ株式会社の異動者向オンボーディング研修 - ITやプログラミングを知って学べるコネクトメディア フューチャーアーキテクト株式会社が実現した新入社員向けIT研修プログラムでタスクフォース制度が主体的な学びと成長を生み出す - IT・プログラミングを知って学べるコネクトメディア コードキャンプDX人材育成研修 - IT・プログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/【IT新入社員研修】オンラインとオフラインの最適バランスを実現したFutureOneの導入事例 - IT・プログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/【新入社員研修】柔軟なハイブリッド型Java研修で実現した新卒20名の成長と成果|サークレイス株式会社 - ITやプログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/現場により近いところにデジタルを根付かせるDX基礎講座研修|株式会社ブリヂストン - ITやプログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/業務の効率化・DX推進に向けたIT人材育成への第一歩|株式会社カナエ - ITやプログラミングを知って学べるコネクトメディア 企業・法人向けのIT・プログラミング研修 - ITやプログラミングを知って学べるコネクトメディア

新着記事

対象者別で探す

子供(小学生・中学生・高校生)向け
プログラミング教室検索する

子供(小学生・中学生・高校生)がロボットやプログラミング言語を学ぶことができるオフラインからオンラインスクールを検索、比較することが可能です。

子供(小学生・中学生・高校生)
プログラミング教室検索する

ITやプログラムなどの
最新情報を検索する

日々、新しいITやプログラミング言語の情報が流れていきますが、特定の情報を時系列でニュースやコラムを確認することができます。

ITやプログラムなどの
最新情報を検索する