FRONT-END DEVELOPER ・ FREELANCE ・ BASED IN TOKYO

tips_css

CSS position: sticky で作るレイアウト4種

December 30, 2022

CSS の position: sticky で作成できるレイアウトのサンプルを作成しました。それぞれCodePen にデモページを用意しています。

Position Sticky とは

position: stickyrelativefixed が組み合わさったものです。 sticky 要素はコンテナ( sticky 要素の親要素)内をスクロール中に指定の位置に固定され、コンテナの終わりまで到達すると相対に戻ります。

1. テキスト + 画像複数

少ないテキストブロックに対してたくさんの画像を見せたい場合のレイアウトです。

テキストエリアと画像エリアを用意します。

<section class="section">
  <div class="text">
    <div class="sticky-item">
      <h2 class="headline">Section 1</h2>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing 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. Duis aute irure d</p>
    </div>
  </div>
  <ul class="img">
    <li class="img__item">
      <img src="images/image01.jpg" alt="">
    </li>
    <li class="img__item">
      <img src="images/image02.jpg" alt="">
    </li>
        
        ...		

    <li class="img__item">
      <img src="images/image08.jpg" alt="">
    </li>
  </ul>
</section>

display: flex で横並びになるようにします。

.section {
  display: flex;
}

固定したい要素(テキストエリア)に固定用の div を追加します。

...

  <div class="text">
    <div class="sticky-item">
      <h2 class="headline">Section 1</h2>
      <p>Lorem ipsum dolor sit amet, consectetur adipisicing 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. Duis aute irure d</p>
    </div>
  </div>

...

固定用の divposition: sticky と固定したい位置を指定します。

.sticky-item {
  position: sticky;
  top: 80px;
}

デモ

2. ブログの目次(Table of Contents)などサイドバー

ブログの目次やナビゲーション、カテゴリー一覧などサイドバーにあたる部分を固定したい場合のレイアウトです。

本文とサイドバーを用意します。

<section class="section">
    <div class="wrap">
    <aside class="sidebar">
      <div class="toc sticky-item">
        <h2>サイドバー</h2>
      </div>
    </aside>
    <div class="content">
            本文エリア
        </div>
  </div>
</section>

display: flex で横並びになるようにします。

.wrap {
  display: flex;
}

固定したい要素(サイドバー)に position: sticky と固定したい位置を指定します。

.sidebar {
  position: sticky;
  top: 4rem;
}

デモ

3. スプリットレイアウト(画面分割)

画面を縦に2つに分割したレイアウトです。片方は固定し、片方はスクロールします。

固定するセクションを1つ、スクロールするセクションを複数、全体を加工 div を用意します。

<div class="block_wrap">
  <section class="block block-1">
    <!-- 固定するセクション -->
  </section>
  <section class="block block-2">
    <!-- スクロールするセクション -->
  </section>
  <section class="block block-3">
    <!-- スクロールするセクション -->
  </section>
  <section class="block block-4">
    <!-- スクロールするセクション -->
  </section>
</div>

display: grid で縦に2分割かつ右側にスクロールさせるセクションが縦に並ぶように指定します。

.block_wrap {
    display: grid;
  grid-template-areas:
    "block1 block2"
    "block1 block3"
    "block1 block4";
  grid-template-columns: 50% 50%;
}

.block {
  height: 100vh;

  &-1 {
    grid-area: block1;
  }
  
  &-2 {
    grid-area: block2;
  }
  
  &-3 {
    grid-area: block3;
  }
  
  &-4 {
    grid-area: block4;
  }
}

固定したい要素(最初のセクション)に position: sticky と固定したい位置を指定します。

.block {
...

  &-1 {
    grid-area: block1;
        position: sticky;
    top: 0;
    left: 0;
  }

...
}

デモ

4. パララックス(紙芝居風)

スクロールすると紙芝居のように次のセクションが前のセクションに被さるように表示されるです。 position sticky によりCSSのみでパララックス風の動きを手軽に実装できるようになりました。

セクションを複数用意します。(コンテンツ量が画面の高さより多い場合、画面よりはみ出る部分は次のセクションによって隠れてしまいます)

<section class="section">
    ...
</section>
<section class="section">
    ...
</section>
<section class="section">
    ...
</section>
<section class="section">
    ...
</section>

セクション全てに position: stickytop: 0; left: 0; を指定します。

.section {
    position: sticky;
  top: 0;
  left: 0;
}

デモ