※このブログではサーバー運用、技術の検証等の費用のため広告をいれています。
記事が見づらいなどの問題がありましたらContactからお知らせください。


【React】CreateReactAppのCSSモジュール機能が便利すぎる

react create-react-app css BEM FLOCSS CSS設計

投稿日:2021年1月23日

このエントリーをはてなブックマークに追加
CreateReactAppにはCSSのセレクタ名の解決を優秀に行うCSSモジュールという機能が存在します。この記事ではCSSモジュールについて解説しています。

はじめに

生のCSSを書く際の問題点

CSSではその性質上セレクタ名を決めることが長年の課題になってきました。

FLOCSSやBEMなどのCSSの設計を勉強したことがある方は、その以上に長いセレクタ名を管理する精神的ストレスを知っていると思います。

JavaScriptのWebフレームワークであるCreateReactAppにはこの課題を解決するCSSモジュールというものが存在します。

環境

この記事の環境は以下の通りです。

  • nodejs==v10.19.0
  • create-react-app==v4.0.1

CSSモジュール機能

CreateReactAppフレームワークで作成したReactアプリケーションにはデフォルトで便利なCSSモジュール機能がついています。

この機能を使用することで、BEMやFLOCSSなどの設計を駆使して面倒で長ったらしいCSSのクラス名を決める必要がなくなります。

実践

まず以下のようなcssファイルがあるとします。

(create-react-appコマンドで生成されるサンプルのcssです)

App.css
.App {
  text-align: center;
}

.App-logo {
  height: 40vmin;
  pointer-events: none;
}

@media (prefers-reduced-motion: no-preference) {
  .App-logo {
    animation: App-logo-spin infinite 20s linear;
  }
}

.App-header {
  background-color: #282c34;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
}

.App-link {
  color: #61dafb;
}

@keyframes App-logo-spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

このCSSファイルを読み込ませる時、通常なら以下の様にします。

(これもコマンドで作成されるサンプルファイルです)

App.js
import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

ではこれをCSSモジュールを使う形に変更してみましょう。

CSSモジュール機能を使うにはまずCSSファイルの拡張子を.cssから.module.cssに変更します。

今回の場合はApp.cssApp.module.cssに変更します。

次にReactのJavaScriptコードを変更します。

まず呼び出す側のスクリプトのCSSのimport文をデフォルトexportのimportに変更します。次に、対象のクラス名の参照をimportした変数からドット(.)またはブラケット([])で呼び出します。

ハイフンのついたクラス名はドット.でアクセスできない為ブラケット[]で参照しましょう。

import React from "react";
import logo from "./logo.svg";
import style from "./App.module.css"; // import文を変更

function App() {
    return (
        <div className={style.App}>
            <header className={style["App-header"]}>
                <img src={logo} className={style["App-logo"]} alt="logo" />
                <p>
                    Edit <code>src/App.tsx</code> and save to reload.
                </p>
                <a
                    className={style["App-link"]}
                    href="https://reactjs.org"
                    target="_blank"
                    rel="noopener noreferrer"
                >
                    Learn React
                </a>
            </header>
        </div>
    );
}

export default App;

するとビルド時にcss、html双方のセレクタが{コンポーネント名}_{モジュールのクラス名}__{ランダム値}に書き直されます。

ビルド後のhtmlの一部
[...]

<div class="App_App__16ZpL"></div>

[...]
ビルド後のstyleの一部
[...]

.App_App__16ZpL {
    text-align: center;
}

[...]

これによってビルドされた後のコードでそれが重複することは決してないため、CSSの管理が非常に楽になります。

注意点

上の例の通り、CSSモジュール機能ではハイフン(-)のついたクラス名はドット(.)で参照できません。

.module.cssファイルのセレクタ名にはハイフンを使わず、できるだけ短い名前をつけるのが良いでしょう。

もしつけるとしてもアンダーバー(_)を使う様にしましょう。

このエントリーをはてなブックマークに追加


関連記事

記事へのコメント