React CSS Modules
1. CSS Modulesとは?
CSS Modules を使用すると、特定のコンポーネントに対してのみ有効な、ローカルにスコープされたCSSを記述することができます。
これにより、CSSクラス名の衝突(コンフリクト)を防止し、スタイルのメンテナンス性を大幅に向上させることが可能です。
注意: CSS ModulesはReactのコアライブラリの一部ではありませんが、多くのReactビルドツール(Create React AppやViteなど)で標準サポートされています。
CSS Modulesを使用する場合、ファイル名を .module.css という拡張子にする必要があります。利用する際は、そのファイルをReactファイルにインポートして使用します。
2. CSSモジュールの作成
ボタンのスタイルを定義する Button.module.css という名前のCSSモジュールを作成してみましょう。
2.1 スタイル定義の例
Button.module.css というファイルを作成し、以下のスタイルを記述します。
Button.module.css
.mybutton {
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}3. CSSモジュールの使用方法
作成したCSSモジュールをコンポーネントにインポートして適用します。
3.1 実装例
CSSモジュールを使用する Button コンポーネントを作成します。
import styles from './Button.module.css';
function App() {
return (
<div>
{/* stylesオブジェクトを介してクラスにアクセス */}
<button className={styles.mybutton}>
マイ・ボタン
</button>
</div>
);
}3.2 コードの解説
- CSSモジュールから styles オブジェクトをインポートします。
styles.mybuttonを使用してmybuttonクラスにアクセスします。- ブラウザでレンダリングされる際、ボタンの実際のクラス名は一意の文字列(例:
_mybutton_q1obu_1)に変換されるため、他のファイルとの衝突が起こりません。
4. 複数のクラスの適用
一つの要素に複数のクラスを適用することも可能です。
4.1 CSSの定義
Button.module.css にスタイルを追加します。
Button.module.css
.mybutton {
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}
.primary {
background-color: #007bff;
color: white;
}
.secondary {
background-color: #6c757d;
color: white;
}4.2 コンポーネントでの適用例
テンプレートリテラルを使用して、複数のクラスを結合します。
import styles from './Button.module.css';
function App() {
return (
<div>
<button className={`${styles.mybutton} ${styles.primary}`}>
プライマリ・ボタン
</button>
<button className={`${styles.mybutton} ${styles.secondary}`}>
セカンダリ・ボタン
</button>
</div>
);
}5. クラスの継承 (composes)
CSS Modulesでは、composes キーワードを使用してクラスを組み合わせることができます。これは、あるクラスが別のクラスのスタイルを継承することを意味します。
先ほどの例では、primary と secondary の両方が mybutton のスタイルに依存していました。これを composes を使って整理してみましょう。
5.1 composesの使用例
Button.module.css
.mybutton {
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
}
.primary {
composes: mybutton;
background-color: #007bff;
color: white;
}
.secondary {
composes: mybutton;
background-color: #6c757d;
color: white;
}このように定義すると、コンポーネント側では primary や secondary を指定するだけで、自動的に mybutton のスタイルも適用されます。
import styles from './Button.module.css';
function App() {
return (
<div>
<button className={styles.primary}>
プライマリ・ボタン
</button>
<button className={styles.secondary}>
セカンダリ・ボタン
</button>
</div>
);
}6. グローバルクラス (Global Classes)
通常、CSSモジュール内のクラスはインポートしたコンポーネント内でのみ有効です。これは、クラス名にファイル名のハッシュ値などが付加されるためです。
しかし、特定のクラスをグローバル(全体)で利用可能にし、他のコンポーネントからも参照したい場合があります。その場合は :global 構文を使用します。
6.1 実装例
BlueHeader.module.css というファイルでグローバルクラス .myheader を定義します。
BlueHeader.module.css
:global(.myheader) {
padding: 10px 20px;
font-size: 50px;
color: white;
background-color: dodgerblue;
}:global でラップされたクラスは、_myheader_q1obu_1 のようなユニークな名前には変換されず、そのまま .myheader として扱われます。
6.2 コンポーネントでの使用
インポートした styles オブジェクトを介さず、通常の文字列としてクラス名を指定できます。
import styles from './BlueHeader.module.css';
function App() {
return (
<div>
{/* styles.myheader ではなく文字列で指定 */}
<h1 className="myheader">
マイ・ヘッダー
</h1>
</div>
);
}7. グローバルクラスとローカルクラスの併用
一つのCSSモジュール内で、グローバルクラスとローカルクラスを混在させることも可能です。
7.1 実装例
MyStyles.module.css
:global(.myheader) {
padding: 10px 20px;
font-size: 50px;
color: white;
background-color: dodgerblue;
}
.myparagraph {
font-size: 20px;
color: white;
background-color: purple;
}7.2 コンポーネントでの使用
import styles from './MyStyles.module.css';
function App() {
return (
<div>
{/* グローバルクラスは文字列で指定 */}
<h1 className="myheader">
マイ・ヘッダー
</h1>
{/* ローカルクラスはstylesオブジェクトから指定 */}
<p className={styles.myparagraph}>
マイ・パラグラフ
</p>
</div>
);
}