78
46

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ReactでCSSを使う

Last updated at Posted at 2018-09-21

ReactでのCSS記述

React単体ではスタイリング機能は持っていません。そのため何らかのプラグインだったりを導入して実現させるのですが、個人的に一番しっくりきたCSS-Modulesについて解説します。

スタイル記述についての個人的要望は以下の通り。

  • CSSは開発環境下では別ファイルで管理したい
  • プラグイン独自のCSS記述ではなく通常の書き方で記述したい
  • SCSSが使いたい

この要件を満たす書き方が出来るのがCSS-Modulesでした。

webpackの記述

CSS-Modulesを組み込むにはwebpackを使ってCSSの読み込み方を少し変更する必要があります。
といってもReact自体がWebpackで書き出していると思いますのでそれほど問題はないと思います。
具体的なソースは以下の通り。

webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options :{
              modules : true
            }
          },
          'postcss-loader','sass-loader'
        ],
      },
      /* ... 省略 ... */
    ]
  }
}

上記ソースは該当部分だけ書き出しています。
通常のSASS組み込みとstyle-loaderでソース内に含める記述に加えて、css-loaderのオプションで modules : true にすればOKです。

CSS-Modulesの記述方法

CSS側は一般的なCSS(SCSS)記述でOKです。

style.scss
.news{
  background-color:#eee;
  border:1px solid #aaa;
  padding:10px;

  li{
    font-size:2.0rem;
    border-bottom:1px solid #aaa;
    
    &.new{
      &:before{
        content:'new!';
        display:inline-block;
        background-color:#3333aa;
        border-radius:5px;
        padding:3px;
      }
    }
  }
}

Reactはimportでstyleファイルを読み込み、render内のclassName属性に{インポート名.クラス名}の形で記述します。

newsComponent.jsx
import React from 'react'
import ReactDOM from "react-dom"

import styles from './style.scss'

class NewsComponent extends React.Component {
  render(){
    return(
      <div className={styles.news}>
        <ul>
          <li className={styles.new}>お知らせ3</li>
          <li>お知らせ2</li>
          <li>お知らせ1</li>
        </ul>
      </div>
    )
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<NewsComponent />, rootElement);

これだけです。めちゃくちゃ簡単でコードもシンプル!

クラスの複数指定

複数クラスを割り当てたい場合は、単純にテンプレートリテラルの記述で対応できます。

こんな感じ。↓

multi.jsx
<div className={`${styles.item} ${styles.new}`}>

レンダリング結果

実際これをレンダリングすると、header内のタグにCSSが記述され、body内のclassNameのところにはクラス名が記述されます。
ただしクラス名にはランダム文字列っぽい名称が割り当てられ、それによってCSSの名前空間が確保されるようです。
逆に言えば、***CSSを読み込んだコンポーネント内でのみ、そのクラス名のCSS記述は有効になります。***ただしHTMLタグ要素に直接指定しているスタイルはすべて有効となるので、上位コンポーネントにてreset.CSSのようなものを読み込めば、そのルールは下層コンポーネントにも反映されます。

書き出されるソースはこんな感じ↓

index.html
<div class="eqhQs48VWk9seAoZQCOHV">
  <ul>
    <li class="LLe7eCuHxMDShinsdvEWu">お知らせ3</li>
    <li>お知らせ2</li>
    <li>お知らせ1</li>
  </ul>
</div>

まとめ

CSS-ModulesはClassNameにクラスを指定するだけで、CSS自体の書き方も独自ルールが不要なことから、導入の閾値はかなり低いのではないでしょうか。また読み込んだファイルの範囲で名前空間が確保されるので、コンポーネントを超えたスタイルの不具合が発生しにくく通常のHTMLの感覚に近い扱い方が出来ます。
HTMLコーディング上がりの方や、デザイナーと分業で構築される方にはオススメです。

78
46
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
78
46

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?