React 速習チュートリアル

React CSS-in-JS

1. CSS-in-JSとは?

CSS-in-JS とは、JavaScriptコード内に直接CSSを記述するスタイリング手法のことです。

このアプローチを採用することで、以下のことが可能になります:

  • JavaScriptを使用してCSSを記述できる
  • コンポーネントごとにスコープ化されたスタイルを作成できる
  • Props に基づいてスタイルを動的に変更できる
  • CSSクラス名の衝突を回避できる

本チュートリアルでは、最も人気のあるライブラリの一つである styled-components を使用して解説します。

2. はじめに

CSS-in-JSはReactのコアライブラリには含まれていませんが、Vite、Webpack、Create React Appなどのビルドツールを使用して簡単にインストールできます。

styled-components をインストールするには、以下のコマンドを実行します。

npm install styled-components

インストール後、.jsx ファイル内に直接CSSを記述し始めることができます。

2.1 実装例

.jsx ファイル内にスタイルを直接挿入する例です。

import styled from 'styled-components';

// styled.h1 を使用してスタイル付きコンポーネントを定義
const MyHeader = styled.h1`
  padding: 10px 20px;
  background-color: #007bff;
  color: white;
`;

function App() {
  return (
    <>
      <MyHeader>ようこそ!</MyHeader>
    </>
  );
}

CSS-in-JSを使用しない場合、通常は以下のいずれかの方法をとる必要があります。

  • 別の .css ファイルにCSSを記述し、Reactコンポーネントにインポートする
  • インラインスタイル(inline styles)を使用する

注目ポイント:

  • styled オブジェクトを使用してコンポーネントを作成します。
  • スタイルは バッククォート(`) で囲まれた テンプレートリテラル 内に記述します。
  • 通常のCSS構文がそのまま使用可能です。

3. Styled ComponentsにおけるPropsの活用

CSS-in-JSの非常に強力な機能の一つは、Props を使用してスタイルを動的に制御できる点です。

例えば、「プライマリ」と「セカンダリ」の2つのボタンを作成し、btntype プロップスの値に応じて背景色を切り替えてみましょう。

3.1 実装例

import styled from 'styled-components';

const Button = styled.button`
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  /* Propsの値に基づいて背景色を動的に決定 */
  background-color: ${props => props.btntype === 'primary' ? '#007bff' : '#6c757d'};
  color: white;
  cursor: pointer;
`;

function App() {
  return (
    <div>
      <Button btntype="primary">プライマリ・ボタン</Button>
      <br />
      <br />
      <Button>セカンダリ・ボタン</Button>
    </div>
  );
}

4. スタイルの拡張 (Extending Styles)

複数の要素で同じスタイルを共有するもう一つの方法は、既存の styled component を拡張(継承)することです。

例えば、基本となる Button コンポーネントのスタイルを継承しつつ、それぞれ異なる背景色を持つ PrimaryButtonSuccessButton を作成できます。

4.1 実装例

import styled from 'styled-components';

// 基本のボタン
const Button = styled.button`
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  color: white;
  cursor: pointer;
`;

// Buttonコンポーネントを拡張
const PrimaryButton = styled(Button)`
  background-color: #007bff;
`;

// Buttonコンポーネントを拡張
const SuccessButton = styled(Button)`
  background-color: #28a745;
`;

function App() {
  return (
    <div>
      <PrimaryButton>プライマリ</PrimaryButton>
      <SuccessButton>サクセス(成功)</SuccessButton>
    </div>
  );
}

5. コンポーネントスコープのスタイル

CSS Modules と同様に、CSS-in-JSで作成されたスタイルはコンポーネントにスコープされます。

これらには一意(ユニーク)なクラス名が自動的に割り振られ、そのコンポーネント内でのみ有効となります。
上記の例でページのソースを表示すると、ボタンには bSOFjJpkxvl といった一意のクラス名が付与されており、<style> セクション内の同じクラス名のCSSを参照していることがわかります。

6. グローバルスタイル (Global Styles)

時には、アプリケーション全体に適用されるグローバルスタイルを作成したい場合もあります。その場合は createGlobalStyle を使用します。

6.1 実装例

import { createGlobalStyle } from 'styled-components';

// アプリケーション全体に適用されるスタイルを定義
const GlobalStyle = createGlobalStyle`
  h1 {
    color: white;
    background-color: purple;
    font-family: Arial, sans-serif;
  }

  .myparagraph {
    font-family: courier, monospace;
    color: blue;
  }
`;

function App() {
  return (
    <>
      <GlobalStyle />
      <h1>ようこそ!</h1>
      <p className="myparagraph">この段落はグローバルスタイルで装飾されています。</p>
    </>
  );
}

createGlobalStyle で定義されたスタイルはユニークな名前が付加されず、通常のクラス名としてすべてのコンポーネントで使用可能になります。