JavaScriptを有効にしてください

画面に表示されたことを検出して、Styled ComponentsでCSSを切り替える

 ·  ☕ 3 分で読めます  ·  ✍️ _da1kong

はじめに

いろいろなサイトを見ていると、画面へ入る瞬間にヌルッと下から出てくる UI を見つけました。以下のようなものです。

ezgif.com-gif-maker.gif

画面に入るとヌルッとしたから出てくるものですが、GIF だと分かりづらいのでちゃんと見たい人は私が作成したページで見ることができます。

この UI が個人的に結構気に入ったので、React での実装例として共有します。

使用したライブラリ

  • react-intersection-observer: 8.29.0
  • @emotion/core: 10.0.28

react-intersection-observer とは

react-intersection-observerとは画面の要素がビューポート(ブラウザ上に表示されている画面)に入った時、もしくは出た時に検知してくれる React 用のライブラリです。内部的にはIntersection Observer APIが使われており、React で使いやすいように hooks などで提供してくれています。

react-intersection-observer は以下のように使用できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// Usage of Hooks, useInView (TypeScript)
import React from "react";
import { useInView } from "react-intersection-observer";

const Component: React.FC = () => {
  const { ref, inView } = useInView({
    /* Optional options */
    threshold: 0,
  });

  return (
    <div ref={ref}>
      <h2>{`Header inside viewport ${inView}.`}</h2>
    </div>
  );
};

Usage Hooks 🎣 useInView

検知したい HTML の親要素の ref 属性に対して、useInView で提供されている ref を割り当てることで、ビューポートに表示されているかいないかを検知できるようになります。inView にはデフォルトは flase であり、検知すれば true を返します。これを使用して CSS を切り替えます。

Styled Components で inView の値によって CSS を切り替える

emotion には props を受け取って CSS を切り替えられます。

1
2
3
4
5
import styled from "@emotion/styled";

const Button = styled.button`
  color: ${(props) => (props.primary ? "hotpink" : "turquoise")};
`;

Styled Components Changing based on props

この機能を使うことで inView の値に応じて CSS を切り替えることができます。例えば、最初に例として挙げたビューポートに入った瞬間ヌルッとしたから出てくる UI は以下のように実現しています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import React from "react";
import { useInView } from "react-intersection-observer";
import styled from "@emotion/styled";

const Component: React.FC = () => {
  const { ref, inView } = useInView({
    /* Optional options */
    threshold: 0,
  });

  return (
    // inView属性を割り当てる
    <Section ref={ref} inView={inView}>
      <h2>{`Header inside viewport ${inView}.`}</h2>
      <p>スクロールとするとヌルッと出てくるよ!</p>
    </Section>
  );
};

// inViewの型を定義
interface Props {
  inView: boolean;
}

// inViewがtrueになると透明度が0.5から1になり、50px下から移動してくる
const Section = styled.section<Props>`
  transition: all 1s ease;
  transform: ${(props) =>
    props.inView ? "translateY(0)" : "translateY(50px)"};
  opacity: ${(props) => (props.inView ? 1 : 0.5)};
`;

まとめ

react-intersection-observer と Styled Components を紹介しました。ユーザーの動作に応じて CSS を切り替えると動きのある UI を実現できます。これらの機能を使用して自分の Portfolio を作成したので、ご興味があれば参考にどうぞ。

他にもこれらの機能を使って面白い実装などありましたら、是非コメントで教えてください。

共有

Daichi (@_da1kong)
著者
_da1kong
Software Developer