Reactで作成するコンポーネントにスタイルの適用方法は以下の通りです。
- クラス名
- インラインスタイル
- CSS Modules
- CSS in JS
最初のクラス名と言うには一般的なCSSファイルを別途用意してhtmlに読み込んで適用する方法です。
注意点:テンプレートになるjsx上でのclassの適用はclassではなくclassNameになります。
<button className="hoge">
Reactのスタイリングで個人的に現実的なのは最初のクラス定義と最後のCSS in JS です。
その方法も色々とあるのですが、今回はstyled-componentsを取り上げます。
Reactの作業環境はreact-simple-boilerplateを利用します。 react-simple-boilerplateについてはREADMEを読んで頂くか、簡単な使い方をこちらに書いておりますので必要な場合はご覧ください。
react-simple-boilerplateはSASSを使う想定になっています。
ですのでstyled-componentsをコンポーネントに追加する必要があります。
# npmの場合
npm install --save styled-components
# yarnの場合
yarn add styled-components
react-simple-boilerplateのhome.scssに以下の記述があるのですが今回は削除して起きます。
// home.scss
h1 {
color: tomato;
}
※本当はwabpack.config.jsを調整すべきですが、今回の本題はそこでは無いので割愛します。
react-simple-boilerplateのsrcディレクトリ配下にApp.jsxと言うファイルがあります。
詳細は省きますが、こちらがローカルホストで表示される部分のコンポーネントになっています。
初期の状態では以下の通りです。
App.jsx
import React, {Component} from 'react';
class App extends Component {
render() {
return (
<h1>Hello React :)</h1>
);
}
}
export default App;
この状態で仮にh1要素にスタイルを適用する場合はCSSで以下のようにスタイルを定義します。
h1 {
text-align: center;
color: #db34db;
font-size: 10em;
}
styled-componentsでのスタイリングは以下のようになります。
App.jsx
import React, {Component} from 'react';
import styled from 'styled-components';
const PageHeader = styled.h1`
text-align: center;
color: #db34db;
font-size: 10em;
`;
class App extends Component {
render() {
return (
<PageHeader>Hello React :)</PageHeader>
);
}
}
export default App;
詳細は以下になります。
まずstyled-componentsをimportします。
import styled from 'styled-components';
これでstyled-componentsを利用出来るようになります。
スタイルを定義しているのは以下の部分です。
こちらはコンポーネントを定義している外で行います。
const PageHeader = styled.h1`
text-align: center;
color: #db34db;
font-size: 10em;
`;
ここではPageHeaderと言うconstを定義しています。
これをローカルホストで立ち上げ、デベロッパーツールなどで確認して見ると
実際に書き出されたコードを見る事が出来ます。
# npmの場合
npm start
# yarnの場合
yarn start
上記を実行後に以下のURLを確認
http://localhost:3000
上記のURLをブラウザで開き、デベロッパーツールなどで確認した書き出されたコードからReactによって作られた部分を抜粋しました。
<!doctype html>
<html lang="en">
<head>
// 省略
<style data-styled-components="">
/* sc-component-id: sc-bdVaJa */
.sc-bdVaJa {} .dAKOIS{text-align:center;color:#db34db;}
</style>
// 省略
</head>
// 省略
<div id="react-root">
<h1 data-reactroot="" class="sc-bdVaJa dAKOIS">Hello React :)</h1>
</div>
// 省略
jsxでを指定している部分がこちらになります。
<PageHeader>Hello React :)</PageHeader>
改めてスタイルを定義している部分です。
const PageHeader = styled.h1`
text-align: center;
color: #db34db;
font-size: 10em;
`;
この比較でお分かりの通り、jsxにはHTMLのh1要素を記述せず、スタイルを定義するために作られた
PageHeaderの方にh1を指定するようになっています。
const PageHeader = styled.h1 ...
またhtmlのhead要素内に書き出されているStyleは以下のようにユニークな名前になっており
結果的にスタイルの指定範囲を絞っている形になっています。
<style data-styled-components="">
/* sc-component-id: sc-bdVaJa */
.sc-bdVaJa {} .dAKOIS{text-align:center;color:#db34db;}
</style>
Reactのstyled-componentsの実装をとても簡単ではありますが検証しました。
プログラムの目線で見るとCSSは全てがグローバルになってしまうため、扱いが難しいものでしたが CSS in JSの手法をとるとその問題も解決します。
ReactのCSS in JSはいくつかやり方があるそうですが、現状(2018/08)ではstyled-componentsが良さそうです。
ただ、CSSのグローバル問題に関してですが、CSSを長く扱ってきた私のような人間からするとOOCSSのようなもので解決出来るのでは? と疑問に思う事もあります。
この議論は色々な状況で答えが変わってきそうなのでここでは一旦、おいておこうと思います。