Reactにスタイルを当てる|React

当てる方法はいくつかある。

従来のHTML+CSS形式

classを設定してスタイルを適用する。

ただしclassが予約語のため使用できない。JSX中ではclassをclassNameと記述すればclassとして適用される。

<section className="wrapper">
〜
</section>

テンプレートにCSSファイルを読み込むか、<style>で直に書き込む。

一番単純でわかり易い。

インラインで記述する

以下のような形でコンポーネント単位でスタイルを定義し、テンプレート側にインラインとして埋め込む。

const style: React.CSSProperties = {
  color: 'blue',
  background: '#aaccff',
  padding: '0.5em',
  fontWeight: 'bolder',
  borderRadius: '0.5em',
};
export const Hello: React.FC = () => {
  return <div style={style}>Hello</div>;
};

予め記述するスタイルの書き方が色々あるっぽいけど、書き方が特殊で生のCSSとの互換性、親和性に欠けて現実的ではない。

たぶん使うことは無いので詳細は割愛。

CSS Modules

cssファイルをコンポーネント単位で用意して読み込むやり方。

以下のような形。

import * as React from 'react';
import css from './hello.css';

export const Hello: React.FC = () => {
  return <div className={css.box}>Hello</div>;
};

コンポーネントごとに名前空間を独立させることができるのでclass名の管理が楽になるメリットがある。

シンプル実装

webpackでライブラリを追加して、jsでcssを扱えるようにする。

css-loaderとstyle-loaderをインストール。

$ npm install --save-dev css-loader style-loader

webpack.config.jsの該当箇所にcss-loaderとstyle-loaderに関する記述を追加。

module.exports = {
  〜
  module: {
    rules: [
      {
        〜
      },
//この辺を追加
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader']
      },
    ]
  }
};

コンポーネントごとに独立させる

上記の実装だとグローバル指定となる。コンポーネント単位で切り離すには以下。

webpack.config.jsに追加したstyle-loader,css-loader周りを以下のように変更する。

これにより、css内に記述したclassが、ここで定義したフォーマットに変換されるようになる。

      {
        test: /\.css$/,
        use: [
          {
            loader: 'style-loader',
          },
          {
            loader: 'css-loader',
            options: {
              modules: {
                localIdentName: '[name]__[local]___[hash:base64:5]',
              }
            }
          }
        ]
      },

コンポーネント側を以下のように変更。

import React from "react";
import css from "./Layout.css"

export default class Layout extends React.Component {
  render() {
    const title = "Welcome Hateruma-island"
    return (
      <section className={css.wrapper}>
        <div className={css.container}>
          〜
        </div>
      </section>
    );
  }
}

cssファイルをcssとしてimportし、classNameに対してcss.XXXという変数で記述すると、webpack.config.jsのlocalIdentNameとして定義したフォーマットに変換されたものがclassとして出力される。

ここまでで基本的には完了。ただしTypeScriptを使用している場合にはエラーが出るのでそれへの対応が必要。

でも一旦ここではそこまで言及しない。

CSS in JS ライブラリ

コンポーネント内でスタイル定義できるようにするライブラリがある。ざっと見た感じ特殊な書き方が求められる感じみたいなので各論として必要に応じて別に勉強するほうがよさそう。

雑感としてReactでスタイルを当てるやり方はCSSをjsに無理やり入れ込もうとしていることでいちいち無理をしていて、その解決策がいろんな形で提示されているけどどれもちょっとマニアックで、汎用性に欠ける。

結局CSSをグローバルに使いたい場面は出てくるはずで、それがHTML的なコンポーネント管理と一致はしないと思うので、グローバルにCSS設計して扱ったほうが根本的には楽じゃないかと個人的には思う。

おそらくエンジニア視点で自分たちで管理しやすい部分にCSSを取り込もうとする試行錯誤の過程ではないかと思われるが、たぶんやり方として片手落ちな部分も多々あると思うので、今後も変わっていくのでは。