前置き
本記事では、Reactで開発する際の主な5つのcssの設計方法について紹介しています。個人的には4.css in js か5.cssフレームワークを用いて開発する方法がおすすめです。
cssファイルでスタイリングを管理することの課題
本記事を読む上で、前提としてcssファイル(cssのクラスを単純にhtmlに適用させる)でスタイリングを管理することの課題を知っておく必要があると考えます。CSSは全てがグローバル定義であるため、CSSファイルを見ただけでそのスタイルの影響範囲を理解することは難しい。これは保守性の観点からあまりよろしくないと言える。
そのため、cssのスコープを可能な限り狭めることで保守性を高めるためのいくつかの手法が存在している。(影響範囲をWebアプリケーションのいわゆるコンポーネント単位で閉じようという考え)
インラインスタイル
jsxのstyle属性を使用して記述する方法
書き方
オブジェクトを作り、それをjsxのstyle属性に適用する。
// cssのプロパティはキャメルケースで書く必要がある。(jsで"-"が認識されないため)
const divStyle = {
color: 'blue',
backgroundImage: 'url(' + imgUrl + ')',
};
function HelloWorldComponent() {
return <div style={divStyle}>Hello World!</div>;
}
メリット
- 導入が簡単
デメリット
- パフォーマンスの観点から、公式では非推奨(毎回cssのオブジェクトを生成することになるため)とされている。
- cssで擬似要素を使用することができない
cssのclass
cssファイルにclassを定義し、htmlに適用する一番シンプルな方法
書き方
cssでclassを作成し、それをjsxのclassNameに適用する
.btn {
width: 50%;
padding: 1em;
background: #fff;
}
import React, { useCallback, useState, useEffect } from "react";
const Button = (props) => {
return (
<button
className={"btn"}
onClick={() => props.onClick(props.argument)}
>
{props.name}
</button>
);
};
export default Button;
メリット
- 導入が簡単
- 馴染みがある書き方
デメリット
- 通常のcss管理と同様に、命名規則や重複を避けるための工夫が必要(BEMなど)。
- どの箇所に適用されているclassなのかという判断が難しい
css modules
cssファイルをjsファイルからモジュールとしてimportし、適用する方法(1コンポーネント毎に1ファイル)
webpackのcss-loaderにより、各cssのclass名がエンコードされるため、セレクタ名の衝突が起こらず、結果的にローカルスコープを得た扱いになる。
css-loader(importやrequireでjavascriptからCSSファイルを読むことができるツール)が以下のように変換してくれる。
<変換前>
.text-green {
color: green;
}
<変換後>
._23_aKvs-b8bW2Vg3fwHozO {
color: green;
}
書き方
※事前に、webpackのmodules設定を行う必要あり。
ボタン用のcssファイルを用意し、それをjsからimportしてjsxのclassNameに適用する
/* Button.css */
.button {
width: 50%;
padding: 1em;
background: #fff;
}
import styles from './Button.css';
import React, { Component } from 'react';
export default class Button extends Component {
render() {
return <button className={styles.button}>登録する</button>;
}
};
メリット
- css自体は、馴染みがある書き方
- 基本的には、class名の衝突が起きない
デメリット
- 実装には、webpack、babelに依存する
- jsの読み込み順によって、cssの適用順序が変動する
css in JS
jsファイルの中にcssを書いてしまうことで、「jsのコンポーネント専用のcssを作成し、それを適用する」とうイメージ。これによりcssのスコープを可能な限り狭めてしまおうという考え方。
書き方
以下コマンドでstyled-componentsをインストールする
npm install --save styled-components
使用するjsファイルで"styled-components"を読み込み、要素名(h1とかbuttonとか)とcssを適用したコンポーネントを作成し、jsx内で記述する
※そのままではシンタックスハイライトがつかないので、style object(cssをオブジェクト型にして記載する)でcssを書く。
import React, { useCallback, useState, useEffect } from "react";
import styled from "styled-components";
// 名前 = styled.要素名
// style object(cssをオブジェクト型にして記載する)
const PrimaryButton = styled.button({
backgroundColor: "blue",
border: "none",
padding: "4px 14px",
});
const Button = (props) => {
return (
<PrimaryButton
className={props.button}
onClick={() => props.onClick(props.argument)}
>
{props.name}
</PrimaryButton>
);
};
export default Button;
メリット
- cssのスコープがかなり限定され、メンテがしやすくなる。
- ベンダープレフィックスが自動で付与される
- 一度レンダリングしたあとは差分だけレンダリングしてくれる
ベンダープレフィックスも自動で追加されるので、自分でいちいち書く必要がない。ベンダープレフィックスとは、「-moz-や、-webkit-」のことで、クロームなどの各ブラウザで先行実装されている機能を使うための接頭辞
- propsで動的に渡すcssを変更できる
- cssの擬似要素も記載可能
デメリット
- 大きなデメリットは特になし
cssフレームワークを使用
tailwindcssのようなインラインcssフレームワークを使用する
まとめ
いかがでしたでしょうか。本記事では、Reactで開発する際の主な5つのcssの設計方法について紹介しています。cssファイル(cssのクラスを単純にhtmlに適用させる)でスタイリングを管理することの課題を挙げつつ、個人的には4.css in js か5.cssフレームワークを用いて開発する方法がおすすめしています。