1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ReactでCSS Modulesを使う

Posted at

やりたいこと

React Router v7で良さげにCSSを書きたい

選択肢

よく選択肢に上るのは以下のようです

・CSS Modules
・styled-components
・Zero-Runtime

・Tailwind
・Bootstrap

どれが良いとか悪いとかはあまり知らないのですが、今回は簡単そうに見えるCSS Modulesを使う事にしてみます

CSS Modulesとは

CSS Modulesの公式サイトは以下になります
https://github.com/css-modules/css-modules?tab=readme-ov-file

公式は仕様のみ定めていて、これに基づく実装がいくつかあります

・css-loader (Webpack用)
・Parcel
・Vite

css-loaderはCSS Modulesを非推奨としていくようですが、ParcelとViteではそういう動きはなさそうなので、Viteが使われている今どきのReact環境では引き続き使えるようです

今回はReact Router v7をViteで構築していきます

使い方

1. 基本編

React Router v7でnpx create-react-router@latest my-appによりアプリを作ると以下のようなフォルダ構成になると思います

home.tsxにCSSを適用しようと思います

home.module.css
.homeContainer {
  background-color: lightblue;
  padding: 20px;
  text-align: center;
}

cssファイルをimportしてTSX内でclassNameに渡してやるように書くとViteがビルド時に適用してくれます。静的分析利くのでClassNameをTypoする可能性がなくなるのが良いですね

home.tsx
import type { Route } from "./+types/home";
import { Welcome } from "../welcome/welcome";
import styles from './home.module.css';

export default function Home() {
  return <>
    <Welcome />
    <div className={styles.homeContainer}>
      <h1>hoge</h1>
    </div>
  </>
}

hogeの部分がスタイルを適用している部分です

2. stateで表示を変える

stateを使って切り替えることもできます

home.module.css
.homeContainer {
  background-color: lightblue;
  padding: 20px;
  text-align: center;
}

.homeContainer2 {
  background-color: lightcoral;
  padding: 20px;
  text-align: center;
}
home.tsx
import type { Route } from "./+types/home";
import { Welcome } from "../welcome/welcome";
import styles from './home.module.scss';
import { useState } from "react";

export default function Home() {
  const [fuga, setFuga] = useState(true)

  return <>
    <Welcome />
    <div className={fuga ? styles.homeContainer : styles.homeContainer2} onClick={()=>setFuga(!fuga)}>
      <h1>hoge</h1>
    </div>
  </>
}

クリックすると色が変わるようにしてみました

3. composes

公式だと以下に説明があります
https://github.com/css-modules/css-modules/blob/master/docs/composition.md

composes要素にclassNameを書くと、指定したclassNameを継承してCSSを適用できます
例えば以下でfugaを適用すると、color: yellow; background: red;となります

home.css
.hoge {
  color: green;
  background: red;
}

.fuga {
  composes: hoge;
  color: yellow;
}

pseudo classes

以下のように書くと、:hoverまで含めて引き継いでくれます

home.css
.className {
  color: green;
}
.className:hover {
  color: red;
}
.otherClassName {
  composes: className;
  background: black;
}

つまり以下のように書いたのと同じになります

home.css
.otherClassName {
  color: green;
  background: black;
}
.otherClassName:hover {
  color: red;
}

Composing from other files

別ファイルからcomposeすることもできます

css
.otherClassName {
  composes: className from './style.css';
}

Composing from global class names

グローバルスコープのCSSからcomposeすることもできます

css
.otherClassName {
  composes: globalClassName from global;
}

4. 複数のCSSモジュールをimportする

複数のCSSモジュールをimportしてきて使う事もできます
https://github.com/css-modules/css-modules/blob/master/docs/import-multiple-css-modules.md

CSS Modulesでimportしたstylesはオブジェクトであるので、Object.assign()で他のstyleオブジェクトとマージすることができます。以下の場合はDemo.cssファイルとcss-fancy-buttonライブラリをstylesにマージしていて、単独の場合と同じように使うことができます

hoge.tsx
import React from 'react';
let styles = {};
import demo from './Demo.css';
import fancyButton from 'css-fancy-button';
Object.assign(styles, fancyButton, demo);

export default function Demo() {
  return (
    <div className={styles.demo}>
      <button className={styles.fancyButton}>Press Me</button>
    </div>
  );
}

まとめ

良さげに書けるし簡単です
おススメ

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?