【CSS】CSSだけでパララックスを再現する

## はじめに
みなさんは、パララックス（parallax）と聞いたことがあるでしょうか？

最近のサイトは、要素がふわっとフェードインしたり、要素の移動速度が違ったり、
スクロールに応じて色々なアニメーションが発火します。

今まで、このようなアニメーションを実装するには、JavaScriptを使っていたので大変でした。

しかし、Chrome 115で使えるようになった、scroll-driven animationsを使うと、CSSだけでスクロールに合わせたアニメーションを作れるようになります。

この記事では、そんなscroll-driven animationsを使って、パララックスを再現したので紹介します。

## パララックス（parallax）について
まずパララックス（parallax）にて解説します。

### パララックス（parallax）とは？
パララックスとは、視差効果のことで、
Webサイトにおいては、パララックスはスクロールなどの動作に応じて、
複数のレイヤー（層）にある要素を異なるスピードで動かすことで、
「**立体感や奥行きの演出**」、「**フェード・拡大縮小・回転などの視覚的エフェクト**」を演出する
アニメーションを指します。

### パララックス（parallax）を使ったサイトの例
*1. Instagramの公式サイト*
https://about.instagram.com/ja-jp/

*2. 星野リゾートの界タビ20s*
https://www.hoshinoresorts.com/sp/kaitabi20s/

*3. パララックスアニメーションのライブラリー*
https://dixonandmoe.com/rellax/

## パララックス（parallax）の作り方
### ⚪︎ パララックス（parallax）の基本・構造を理解する

パララックス（parallax）の基本・構造のポイントは以下の通りです。

:::note
**ポイント**
・ **手前にあるもの**は、**スクロール量より早く移動する**。
・ **奥にあるもの**は、**スクロール量よりゆっくり移動する**。
:::

![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/764efca9-0021-b7ef-76cd-b025c608fd01.png)

**イメージしてください。🤔**

*電車に乗って窓から景色を見ている時、遠くに見える家はどのように移動して見えるでしょうか？*
→ 遠くに見える家はゆっくり移動しているようにみえますよね！？

*では反対に、近くに見える家はどのように移動して見えるでしょうか？*
→ 近くに見える家は一瞬で移動しているようにみえますよね！？

この現象をUI上に反映させるのが、パララックス（parallax）になります。

**↓ つまり...**

手前にくるような画像や要素は、スクロール量より早く移動し、
奥にくるようは背景画像や要素は、スクロール量よりゆっくり移動させることで、
基本的なHTML要素と視差が起こり、パララックスを表現することができます。


### ⚪︎ CSSだけで、パララックス（parallax）を作成する
#### 1. HTMLを記述する
まずは、HTMLを記載します。
パララックスさせたい要素分の`<div>`を作成します。

それぞれの要素で位置が異なるので、`style`属性を使って、位置を決めています。
CSSアニメーション内で`transform`プロパティを使うため、`transform`を使わずに位置を決めましょう。

今回作成したHTMLはこちらになります。
パララックスの重なりも意識して、`small` → `medium` → `large`の順にしています。

```sample.html
<!-- parallax small object -->
<div style="top: 700px; left: calc(50% - 175px);" class="parallax small"></div>
<div style="top: 900px; left: calc(50% + 75px);" class="parallax small"></div>
<div style="top: 1200px; left: calc(50% - 205px);" class="parallax small"></div>
<div style="top: 1350px; left: calc(50% + 175px);" class="parallax small"></div>
<div style="top: 1550px; left: calc(50% - 275px);" class="parallax small"></div>
<div style="top: 1750px; left: calc(50% + 225px);" class="parallax small"></div>
<div style="top: 1900px; left: calc(50% - 25px);" class="parallax small"></div>
<div style="top: 2100px; left: calc(50% - 275px );" class="parallax small"></div>

<!-- parallax medium object -->
<div style="top: 100px; left: calc(50% - 40px);" class="parallax medium"></div>
<div style="top: 350px; left: calc(50% - 140px);" class="parallax medium"></div>
<div style="top: 600px; left: calc(50% + 210px);" class="parallax medium"></div>
<div style="top: 800px; left: calc(50% - 290px);" class="parallax medium"></div>
<div style="top: 1150px; left: calc(50% - 140px);" class="parallax medium"></div>
<div style="top: 1700px; left: calc(50% + 210px);" class="parallax medium"></div>
<div style="top: 2000px; left: calc(50% - 40px);" class="parallax medium"></div>

<!-- parallax large object -->
<div style="top: -480px; left: calc(50% - 350px);" class="parallax large"></div>
<div style="top: -200px; left: calc(50% + 150px);" class="parallax large"></div>
<div style="top: 0px; left: calc(50% - 150px);" class="parallax large"></div>
<div style="top: 500px; left: calc(50% + 200px);" class="parallax large"></div>
<div style="top: 800px; left: calc(50% - 250px);" class="parallax large"></div>
<div style="top: 1000px; left: calc(50% + 50px);" class="parallax large"></div>
<div style="top: 1300px; left: calc(50% - 300px);" class="parallax large"></div>
```


#### 2. CSSを記述する
次にアニメーション以外のスタイルを記述します。

```sample.css
body {
  background-color: #212529;
  height: 600vh;
  width: 100vw;
}

.wrapper{
  overflow: hidden;
}

.parallax {
  border-radius: 8px;
  box-shadow: 0 0px 16px rgb(0, 0, 0, .16);
  position: absolute;
  aspect-ratio: 1 / 1;
}

.large {
  background-color: #62929E;
  width: 100px;
}

.medium {
  background-color: #B9314F;
  width: 75px;
}

.small {
  background-color: #DDB967;
  width: 50px;
}
```


#### 3. パララックスさせる
今回のパララックスでは、
`.large`のスタイルが当たっているものがスクロール量より早く移動し、
`.medium`のスタイルが当たっているものがスクロール量と同じスピードで移動し、
`.small`のスタイルが当たっているものがスクロール量より遅く移動させます。

そのため、アニメーションは、`.large`と`.small`だけにしています。

`.large`のアニメーションは、スタート位置を500px分だけ下にずらした位置からスタートし、スクロールが終わることには、0pxの位置になるようにすることで、スクロール量より早く移動させています。

`.small`のアニメーションは、スタート位置を500px分だけ上にずらした位置からスタートし、スクロールが終わることには、0pxの位置になるようにすることで、スクロール量より遅く移動させています。

```sample.css
@keyframes parallax-large-anim {
  from {
    transform: translateY(500px);
  }
  to {
    transform: translateY(0px);
  }
}

.large {
  animation: parallax-large-anim linear;
  animation-timeline: scroll();
}

.medium {
  background-color: #B9314F;
  width: 75px;
}

@keyframes parallax-small-anim {
  from {
    transform: translateY(-500px);
  }
  to {
    transform: translateY(0px);
  }
}

.small {
  animation: parallax-small-anim linear;
  animation-timeline: scroll();
}

```


#### 4. 完成形
完成するとこうなります。

<p class="codepen" data-height="400" data-default-tab="result" data-slug-hash="ZEmjzNK" data-editable="true" data-user="sp_degu" style="height: 400px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sp_degu/pen/ZEmjzNK">
  Scroll Driven Animations - parallax</a> by でぐぅー | Qiita (<a href="https://codepen.io/sp_degu">@sp_degu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


## まとめ
この記事では、CSSだけで作るパララックスの作り方と使い方について解説しました。

少しは、パララックスについての理解ができたのではないのでしょうか？？？

Reactを使ったパララックスの解説もしているので、そちらもごらんください。

https://qiita.com/degudegu2510/items/4774a186030b995bdb46

---

最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaに記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510