クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

ReactのCSS設定方法について調べたこと(className属性、style属性、CSS Modules、CSS in JS、CSSフレームワーク)

Reactの続きです。前回はReduxの状態管理を行いました。今回からは、ReactでのCSS設定をいくつか試してみたく思います。初回はCSS設定方法について調べたことをまとめます。className属性、style属性、CSS Modules、CSS in JS、CSSフレームワークを比較します。それではいきましょう!

【目次】

※参考:前回記事
【React】Reduxを事始める(インストール〜ストア、レデューサー、プロバイダー設定) - クモのようにコツコツと

※参考:Reactを習得するためにやったことまとめ
qiita.com

前回のおさらい

Reduxによる状態管理。Reduxをインストールしてストア、レデューサー、プロバイダーを設定。

https://cdn-ak.f.st-hatena.com/images/fotolife/i/idr_zz/20200623/20200623063733.jpg

詳細は前回の記事を参照

※参考:【React】Reduxを事始める(インストール〜ストア、レデューサー、プロバイダー設定) - クモのようにコツコツと

ReactのCSS設定

ReactのCSS設定は大きく分けると下記の5種類あるようだ。

  1. className属性:CSSのclass名の設定をJSXのclassName属性に紐付ける
  2. style属性:style属性(インラインスタイル)でCSS設定を直接埋め込む
  3. CSS Modules:webpackのcss-loaderなどを使ってローカルスコープを作る
  4. CSS in JS:styled-componentsなどを使ってCSS構文の形でJS内に設定
  5. CSSフレームワーク:Material UI、Tailwind CSSなどを使って用意されたスタイルを当てはめる

このうち1と2はすでに経験済み。3〜5は未経験なのでこれから経験していきたい。

1〜4の違いについては下記の記事がとてもわかりやすい!

※参考:Reactのコンポーネントのスタイリングをどうやるか - Qiita

className属性

外部CSSファイルをインポートして、JSXのclassName属性でCSSを設定する方法。

以前触った「Create React App」では「index.js」や「App.js」で「App.css」をインポートしており

import './App.css';

その「App.css」のCSSを打ち替えたら

.App-header {
  background-color: #eee; /* 変更 */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: #333; /* 変更 */
}

.App-link {
  color: #A63744; /* 変更 */
}

CSSスタイルが変わった! https://cdn-ak.f.st-hatena.com/images/fotolife/i/idr_zz/20200513/20200513081229.jpg

※参考:【React】ReactプロジェクトのAppコンポーネントを書き換えてみる - クモのようにコツコツと

全てのCSS設定のスコープがグローバルな関係のため、優先度の干渉が起こり得る。

そのため以前Sass(SCSS)の時にやったようなBEMなどの命名ルールでclass名を設定した方が良さそう。

※参考:【メタ言語】BEMによるclass名をSass(SCSS)とEJSで書いてみる(モジュール事始め) - クモのようにコツコツと

style属性

style属性も以前触った「Create React App」で設定している。

class Img extends React.Component {
  align = 'left';
  style = {};

  constructor(props) {
    super();
    this.align = props.align;
    this.style = {
      textAlign: this.align 
    };
  }
  render() {
    return  <img src={logo} className="App-logo" alt="logo" style={this.style} />
  }
}
  • グローバル変数styleに空のオブジェクト(連想配列)を作成
  • constructor ()this.styletextAlign(CSSではtext-alignの意味)を設定
  • render()style属性でthis.styleを埋め込む
class App extends React.Component {
// 中略
  render() {
    return <div className="App">
      <header className="App-header">
        <div className="App-images">
          <Img align="left" />
          <Img align="center" />
          <Img align="rignt" />
        </div>
        <h1>{this.title}</h1>
        <p>{this.message}</p>
      </header>
    </div>
  }
}
  • 親コンポーネントでImgコンポーネントを読み込む(3つ配置)
  • Imgコンポーネントのalign属性に入れた値がthis.styleに読み込まれる

3つの画像が横並びになった! https://cdn-ak.f.st-hatena.com/images/fotolife/i/idr_zz/20200518/20200518183840.jpg

※参考:【React】Reactプロジェクトでクラスコンポーネント作成、入れ子、ファイル分割まで - クモのようにコツコツと

直接タグのstyle属性にCSS設定を埋め込むので優先度の問題は起こらなそう。JSのオブジェクト(連想配列)なので共通する設定値は変数を埋め込んでもいい。

しかし、落とし穴なのは擬似要素や擬似クラスに適用できないこと!

インライン CSS ではなく、インラインスタイルであるように、style にはスタイルしか渡すことが出来ません。つまり、 :hover や :focus などの擬似要素セレクタやメディアクエリを使うことは出来ません。

※参考:Reactのコンポーネントのスタイリングをどうやるか - Qiita

Reactのリファレンスでもあまり推奨されていない。

style 属性を要素のスタイリングの主要な手段として使うことは一般的に推奨されません。

DOM 要素 – React

CSS Modules(css-loader)

ここからは未体験ゾーンに突入。

CSS Modulesはwebpackのcss-loaderなどを使う。

※参考:css-loader | webpack

cssを一般的なclass名で付けて

.normal {
    background: #eee;
 }

コンポーネントに設定すると

import styles from './submit-button.css';
 
buttonElem.outerHTML = `<button class=${styles.normal}>送信</button>`

こんなclass名になってローカルスコープが作られるようだ!

<button class="components_submit_button__normal__abc5436">送信</button>

参考記事

※参考:CSSモジュール ― 明るい未来へようこそ | POSTD
※参考:webpackのcss-loaderでCSS Modulesをやる - Qiita
※参考:CSS Modules 所感 - morishitter blog

Create React Appでの導入手順(CSS Modulesにデフォルトで対応しているようだ!)

※参考:create-react-appで簡単にcss moduleが使えるようになってた。 - かぷかぷ笑う
※参考:How to use CSS Modules in create-react-app? - RWieruch

CSS Modulesをやめる系の記事

※参考:css-modulesを止めようとしている話(長々とした状況説明編) - saneyuki_s log
※参考:css-modulesを止めようとしている話(具体的な解決編) - saneyuki_s log

なお、React公式サイトではCSS Modulesの記述は見当たらない。

※参考:CSS とスタイルの使用 – React

しかしNext.jsではCSS in JSよりCSS Modulesの方が推奨になったようだ。

※参考:Next.js が CSS Modules を推奨する真相に迫りたい


※2020/12/18追記

実際に触ってみた。

※参考:【React】CSS ModulesでCSSとSass(SCSS)のローカルスコープを作る - クモのようにコツコツと

CSS in JS(styled-components)

CSS in JSはstyled-componentsなどを使ってCSS構文の形でJS内に設定する。

※参考:styled-components

こんな風にJSの中で連想配列ではなくCSS書式で直接設定して

const StyledView = styled.View`
  background-color: papayawhip;
`

const StyledText = styled.Text`
  color: palevioletred;
`

設定したスタイル名をコンポーネント名にして囲う

class MyReactNativeComponent extends React.Component {
  render() {
    return (
      <StyledView>
        <StyledText>こんにちは、しいえすえす・いん・じぇいえす。</StyledText>
      </StyledView>
    )
  }
}

※参考:styled-components: Basics

styled-componentsの参考記事

※参考:styled-componentsの採用と既存資産を捨てた理由 - Cybozu Inside Out | サイボウズエンジニアのブログ
※参考:styled-componentsを使ったCSS設計 - Qiita
※参考:styled-componentsのベーシックな使い方 |

Create React Appでの導入手順

※参考:React: styled-componentsでスタイルをJavaScriptの中に定める - Qiita

その他のCSS in JS

※参考:Reactと一緒に使う時のCSS in JSのライブラリ選定とか所感とか - Qiita
※参考:Free-Style のススメ ~ CSS Modules は解決策ではない - Qiita
※参考:CSS in JS(Elm)したら想像以上に良かった - ジンジャー研究室

CSS in JSをやめる系の記事

※参考:styled-components(CSS in JS)をやめた理由と、不完全なCSS Modulesを愛する方法 - Qiita
※参考:styled-componentsへの最近の感想 - saneyuki_s log


※2020/12/18追記

実際に触ってみた。

※参考:【React】styled-componentsでCSS in JSを事始める - クモのようにコツコツと

UIフレームワーク(Material UI)

UIフレームワークはMaterial UIなどに用意されているスタイルを当てはめる

※参考:Material-UI: A popular React UI framework

Buttonコンポーネントにcolor属性とか予め用意されている。

<Button variant="contained" color="primary">
  Primary
</Button>

例えばcolor属性のprimaryは左から2番目の青いボタン

f:id:idr_zz:20201209071253j:plain

※参考:React Button component - Material-UI

Material UIの参考記事

※参考:React入門 ~Material UI編~ - Qiita
※参考:React + Material-UIで管理画面を作成してみた | DevelopersIO
※参考:Material-UI でインタフェースを作る【Reactで作るマラソンペースメーカー】 - bagelee(ベーグリー)

他にもいろいろ種類がある

※参考:早く・それなりの UI を実現する React コンポーネントセット 16 選 - Qiita

UIフレームワークはVue.jsの時にVuetifyを触ってみた

※参考:Vue.jsを習得するためにやった事 まとめ(随時更新) - Qiita


※2020/12/18追記

実際に触ってみた。

※参考:【React】UIフレームワークMaterial UIでマテリアルデザインを事始める - クモのようにコツコツと

ユーティリティーファーストCSSフレームワーク(Tailwind CSS)

※2021/01/29追記

ユーティリティーファーストのCSSフレームワーク「Tailwind CSS」というものも流行ってきている模様。CSS設定がclass名で完結しつつ、より自由な設定ができる(「Material UIぽい」「BootStrapぽい」のような「ぽさ」が少ない)。

※参考:Tailwind CSS - Rapidly build modern websites without ever leaving your HTML.

Create React Appでの導入方法。

※参考:Install Tailwind CSS with Create React App - Tailwind CSS

こちらもフォローしていきたい。


※2021/02/25追記

ユーティリティファーストとは?

※参考:ユーティリティファーストCSSのススメ〜なぜ、セマンティックなclass命名は失敗するのか?|菱川拓郎|note

「ボタン」などのコンポーネント単位ではなくCSSの一機能単位で設定されたclass名を組み合わせていく。

<button class="transition duration-500 ease-in-out bg-blue-600 hover:bg-red-600 transform hover:-translate-y-1 hover:scale-110 ...">
  Hover me
</button>

上記のclass名でこのようなボタンになる

f:id:idr_zz:20210225063155j:plain

hover:でスタイルが変わる

f:id:idr_zz:20210225063258j:plain

※参考:Transition Property - Tailwind CSS

最後に

ということで、ReactのいろいろなCSS設定方法を調べてみました。className属性とstyle属性に設定する方法はすでに体験済み、CSS Modules、CSS in JS、UIフレームワークは未体験でした。

特にCSS ModulesとCSS in JSはコンポーネント単位でローカルスコープを作る方法なので興味があります!まずはCreate React Appのプロジェクトに導入してみたく思います。

それではまた!


続き書きました!

※参考:【React】CSS ModulesでCSSとSass(SCSS)のローカルスコープを作る - クモのようにコツコツと


※参考:Reactを習得するためにやったことまとめ
qiita.com