[React講座] Reactのスタイリング手法

当ページのリンクには広告が含まれています。
目次

Reactのスタイリング手法

Reactでのスタイリングの選択肢

まずは「種類が多すぎてよく分からない状態」を整理しておきます。

Reactでよく使われるスタイル手法はざっくりこのあたりです:

  1. 素のCSS(グローバルCSS)
    • index.css みたいな普通のCSSファイルに書いて、className で当てる
  2. CSS Modules
    • Button.module.css のようなファイル単位でクラス名をコンポーネントにひも付けるやり方
  3. CSS-in-JS
    • styled-components, Emotion など
    • JSファイルの中に const Button = styled.button みたいに書く
  4. ユーティリティクラス系(Tailwind CSSなど)
    • className="px-4 py-2 bg-blue-500 text-white rounded" みたいに小さなクラスを組み合わせて作る
  5. インラインスタイル
    • style={{ color: 'red', fontSize: 20 }} のようにJSオブジェクトで指定

実務的なおすすめ:

  • 最初のうちは、 「素のCSS or CSS Modules」+インラインスタイル
  • 慣れてきたら、「 Tailwind」か「CSS-in-JS」

一番素直なやり方:グローバルCSS + className

Viteの初期テンプレートだと src/index.css が読み込まれていて、
そこに書いたCSSがアプリ全体に効くようになっています。

① CSSを書く

/* src/index.css */

.app-root {
  max-width: 800px;
  margin: 0 auto;
  padding: 16px;
  font-family: system-ui, sans-serif;
}

.button-primary {
  padding: 8px 16px;
  border-radius: 4px;
  border: none;
  background-color: #2563eb;
  color: white;
  cursor: pointer;
}

.button-primary:hover {
  background-color: #1d4ed8;
}

② Reactで className を付ける

// src/App.jsx
export default function App() {
  return (
    <div className="app-root">
      <h1>Reactアプリ</h1>
      <button className="button-primary">送信</button>
    </div>
  )
}

ポイント:

  • 普通のHTMLと同じ感覚で class の代わりに className
  • 全コンポーネントから .button-primary を使い回せる

デメリット:

  • クラス名がグローバル空間にばら撒かれるので、
    • 名前衝突しやすい
    • どのファイルがどのスタイルを参照しているか追いにくくなる

これを少しマシにするために、
BEM記法(block__element--modifier)を使うこともよくあります:

.todo-item { ... }
.todo-item__title { ... }
.todo-item__delete-button { ... }

最初のうちは「小さめのアプリ + グローバルCSS」で十分ですが、
コンポーネント数が増えてくると「コンポーネントごとにスタイルを閉じたい」欲求が出てきます。
そこで出てくるのが CSS Modules です。

CSS Modules:コンポーネントごとにCSSを閉じ込める

CSS Modulesは、「このコンポーネント専用のCSSファイル」を作って、クラス名の衝突を自動的に防いでくれる仕組みです。

① ファイル名を *.module.css にする

/* src/Button.module.css */
.button {
  padding: 8px 16px;
  border-radius: 9999px;
  border: none;
  background-color: #16a34a;
  color: white;
  cursor: pointer;
}

.buttonDisabled {
  opacity: 0.5;
  cursor: not-allowed;
}

② React側でimportして使う

// src/Button.jsx
import styles from './Button.module.css'

export default function Button({ children, disabled, ...props }) {
  const className = disabled
    ? `${styles.button} ${styles.buttonDisabled}`
    : styles.button

  return (
    <button className={className} disabled={disabled} {...props}>
      {children}
    </button>
  )
}

ここで起きていること:

  • styles.button ⇒ 実際には button_aj3kd9 みたいなユニークなクラス名に変換される
  • Button.module.css のクラスは Button.jsx に閉じたスコープとして扱える
  • 他のコンポーネントで styles.button と書いても、別ファイルなら別物

メリット:

  • クラス名の衝突をほぼ気にしなくていい
  • 「コンポーネント単位のスタイル」という構造になって、頭の整理がしやすい
  • 導入も簡単(Viteならデフォルト対応)

個人開発〜中規模くらいまでなら CSS Modules だけで十分です。

CSS-in-JS:styled-components / Emotion のイメージ

CSS-in-JSは、「JSの中にスタイルを書くことで、完全にコンポーネントとスタイルを1ファイルに閉じる」方向の手法です。

代表的なのが styled-components@emotion/styled

styled-components の例

(※実際に使うには npm install styled-components が必要)

// Button.jsx
import styled from 'styled-components'

const Button = styled.button`
  padding: 8px 16px;
  border-radius: 9999px;
  border: none;
  background-color: #2563eb;
  color: white;
  cursor: pointer;

  &:hover {
    background-color: #1d4ed8;
  }

  &[disabled] {
    opacity: 0.5;
    cursor: not-allowed;
  }
`

export default Button

使う側:

import Button from './Button'

export default function App() {
  return <Button>クリック</Button>
}

メリット:

  • コンポーネントとスタイルが同じファイルにあるので、1ファイル見れば完結
  • propsに応じてスタイルを分岐しやすい
const Button = styled.button`
  background-color: ${({ primary }) => (primary ? '#2563eb' : '#6b7280')};
`

デメリット:

  • ライブラリ導入が必要
  • ランタイムでスタイル生成するため、パフォーマンス・バンドルサイズを気にするケースもある
  • セットアップや設計思想の学習コストがやや重め

最初からこれに突っ込む必要は薄いので、
「CSS Modulesで慣れてきて、もう少し高度なことがしたくなってから」検討でOKです。

Tailwind CSS:ユーティリティクラスで組み立てる

Tailwind CSS は、「小さなユーティリティクラスを組み合わせてデザインするスタイルフレームワーク」です。

例:

<button className="px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded">
  送信
</button>
  • px-4 ⇒ 左右パディング
  • py-2 ⇒ 上下パディング
  • bg-blue-500 ⇒ 背景色
  • hover:bg-blue-600 ⇒ hover時の背景色
  • rounded ⇒ 角丸

メリット:

  • コンポーネントファイル内だけで見た目が完結
  • クラス名を1つ1つ考える必要がない(btn-primaryとか命名しない)
  • 設計次第でコンポーネント設計と相性が良い(小さなパーツの組み合わせ)

デメリット:

  • HTML(JSX)の className が長くなりがち
  • Tailwind特有のクラス名に慣れる必要あり
  • セットアップがやや重め(PostCSS, configなど)

個人開発で「スピード重視」「デザインそこそこ」のときはかなり強いですが、
Reactそのものに慣れる前にいきなりTailwindから入ると、情報量が多くなりコードの理解が難しくなります。

インラインスタイル

インラインスタイルは、

<div style={{ color: 'red', fontSize: 24 }}>テキスト</div>

のように、JSオブジェクトでスタイルを指定する方法です。

特徴:

  • 値は常に文字列ではなくJSの値:
    • fontSize: 24'24px'ではない)
    • backgroundColorbackground-colorではなくキャメルケース)
  • ホバーやメディアクエリ、擬似要素など 普通のCSSで書けることがほとんど使えない

なので、インラインスタイルは 「一時的なスタイル」「計算結果で決まる1〜2プロパティ」くらいに留めるのが現実的です。

例:

const ProgressBar = ({ progress }) => {
  return (
    <div style={{ width: 200, height: 10, backgroundColor: '#e5e7eb' }}>
      <div
        style={{
          width: `${progress}%`,
          height: '100%',
          backgroundColor: '#22c55e',
          transition: 'width 0.2s ease',
        }}
      />
    </div>
  )
}

こういう「動的に変化する幅・色」をサクッと書くときだけ使うのが良いです。

どれを選べばいいか?

React初学〜中級に向かう段階では、こんなステップがおすすめです:

  1. まずは素のCSS + className
    • Viteの index.css でOK
    • 小さなコンポーネントでスタイルを当てる感覚を掴む
  2. 次に CSS Modules を導入
    • コンポーネント単位で *.module.css を作る
    • import styles from './Xxx.module.css' を使いこなす
    • 「デザイン変更時は、そのコンポーネントのCSSだけ見ればいい」状態を目指す
  3. そこから先は好みと案件次第で分岐:
    • デザイン用コンポーネントを量産したい ⇒ CSS-in-JS(styled-components / Emotion)
    • とにかくUIを爆速で組みたい ⇒ Tailwind CSS

いきなり全部を覚えなくてよくて、「CSS Modulesに慣れる」だけで、React×スタイリングとしてはかなり実戦レベルと言って良いです。

まとめ

  • Reactのスタイリングは
    • グローバルCSS
    • CSS Modules
    • CSS-in-JS(styled-components/Emotion)
    • Tailwind CSS
    • インラインスタイル
      など様々だが、まずはCSS Modulesに慣れるのが現実的なライン
  • CSS Modulesは
    • *.module.css を作って import styles from '...'
    • className={styles.xxx} でクラス名衝突を気にせず書ける
  • CSS-in-JSやTailwindは強力だが、Reactの基礎に慣れてから着手でも遅くない
  • インラインスタイルは「計算結果で決まる少数のプロパティ」くらいに絞ると扱いやすい

<<前へ(カスタムフックとロジックの再利用)

>>次へ(パフォーマンス最適化とメモ化)

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次