CSSのstickyで1枚目の表示領域が上に上がりながら2枚目以降を表示する方法

CSSのstickyで1枚目の表示領域を上げながら2枚目以降を表示

WebサイトのLP(ランディングページ)などで、スクロール時に1枚目の要素が上に固定されつつ、下から2枚目の要素が重ね重なるようにして固定が解除され、1枚目ごとスライドして画面外へ去っていくインタラクションがあります。

これはJavaScriptを使わずにCSSの「position: sticky」で実装されており、具体的には以下のようなコードで実装されています。

HTML
<main>
  <section class="section section--sticky section--1">
    <p class="section__text">Section 1</p>
  </section>

  <section class="section section--sticky section--2">
    <p class="section__text">Section 2</p>
  </section>

  <section class="section section--sticky section--3">
    <p class="section__text">Section 3</p>
  </section>

  <section class="section section--sticky section--4">
    <p class="section__text">Section 4</p>
  </section>
</main>
SCSS
$section-colors: (
  1: #ffa69e,
  2: #8fe3a8,
  3: #7fb8ff,
  4: #ffd37a,
);

$text-color: #1f2937;
$section-ratio: 1;

@mixin viewport-size($property, $ratio) {
  #{$property}: 100svh * $ratio;
}

*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.section {
  display: grid;
  place-items: center;
  font-family: sans-serif;
  color: $text-color;
  @include viewport-size(height, $section-ratio);

  &__text {
    text-align: center;
    font-size: 3rem;
  }

  &--sticky {
    position: sticky;
    top: 0;
  }

  @each $index, $color in $section-colors {
    &--#{$index} {
      background-color: $color;
    }
  }
}

See the Pen SCSS Sticky Reveal by iwbjp (@xzdrtugn-the-reactor) on CodePen.

CSSのstickyで1枚目の表示領域を上に上げる方法

前述の例だと下にスクロールするたびに各セクションが下に重なって表示されます。

しかし、最近のアニメ系のWebサイトだと1枚目の表示領域が上に上がりながら2枚目以降を表示させることが多いです。

どうやってやっているのだろうと思っていたのですが、最近Zennにこのやり方の記事が掲載されていました。

【備忘録】CSSのstickyで作る、せり上がりながら背景が見える演出

「-100vhのネガティブマージンとラッパーを200vhとして帳尻を合わせる」だけで良かったようで、HTMLとSCSSのコードにすると以下のようになります。

HTML
<main>
  <section class="section section--cover section--1">
    <p class="section__text">Section 1</p>
  </section>

  <div class="sticky-stage">
    <section class="section section--sticky section--2">
      <p class="section__text">Section 2</p>
    </section>
  </div>

  <section class="section section--3">
    <p class="section__text">Section 3</p>
  </section>

  <section class="section section--4">
    <p class="section__text">Section 4</p>
  </section>
</main>
SCSS
$section-colors: (
  1: #ffa69e,
  2: #8fe3a8,
  3: #7fb8ff,
  4: #ffd37a,
);

$text-color: #1f2937;
$section-ratio: 1;

@mixin viewport-size($property, $ratio) {
  #{$property}: 100svh * $ratio;
}

*,
*::before,
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.section {
  display: grid;
  place-items: center;
  font-family: sans-serif;
  color: $text-color;
  @include viewport-size(height, $section-ratio);

  &__text {
    text-align: center;
    font-size: 3rem;
  }

  &--cover {
    position: relative;
    z-index: 1;
  }

  &--sticky {
    position: sticky;
    top: 0;
  }

  @each $index, $color in $section-colors {
    &--#{$index} {
      background-color: $color;
    }
  }
}

.sticky-stage {
  @include viewport-size(height, $section-ratio * 2);
  @include viewport-size(margin-top, -$section-ratio);
}

See the Pen SCSS Sticky Reveal (first section on top) by iwbjp (@xzdrtugn-the-reactor) on CodePen.

元の記事だとCSSで書かれていますが、このようなWebページのセクションが3つだけということほぼないので、SCSSで書いたほうが編集しやすいです。