Reactの続きです。前回はCSS ModulesでCSSとSass(SCSS)のローカルスコープを作りました。今回はstyled-componentsでCSS in JSを事始めてみます。CSS Modulesと同様にランダムな文字列がclass名が振られる形ですが、CSSファイル読み込みではなくJSファイル内でCSSを設定できます。それではいきましょう!
【目次】
- 前回のおさらい
- CSS in JSとは
- Create React Appをインストール
- styled-componentsインストール
- styled-components設定
- 変数を使う
- 擬似クラス(:hover)の設定
- 子要素の設定
- コンポーネントの入れ子構造
- レンダリングされたHTMLとclass名
- 最後に
※参考:前回記事
【React】CSS ModulesでCSSとSass(SCSS)のローカルスコープを作る - クモのようにコツコツと
※参考:Reactを習得するためにやったことまとめ
qiita.com
前回のおさらい
CSS Modules事始め。CSSだけでなくSass(SCSS)でもローカルスコープが作れた!
詳細は前回の記事を参照。
※参考:【React】CSS ModulesでCSSとSass(SCSS)のローカルスコープを作る - クモのようにコツコツと
その他のReactのCSS設定方法
※参考:ReactのCSS設定方法について調べたこと(className属性、style属性、CSS Modules、CSS in JS、UIフレームワーク) - クモのようにコツコツと
CSS in JSとは
CSS in JSはReactのCSS設定方法の一つでCSS構文の形でJS内に設定する方法。
※参考:ReactのCSS設定方法について調べたこと(className属性、style属性、CSS Modules、CSS in JS、UIフレームワーク) - クモのようにコツコツと
styled-componentsがよく使われている。
styled-componentsの参考記事
※参考:styled-componentsの採用と既存資産を捨てた理由 - Cybozu Inside Out | サイボウズエンジニアのブログ
※参考:Free-Style のススメ ~ CSS Modules は解決策ではない - Qiita
※参考:CSS in JS(Elm)したら想像以上に良かった - ジンジャー研究室
Create React Appをインストール
今回もCreate React App環境で導入したい。こちらの記事を参考に。
※参考:React: styled-componentsでスタイルをJavaScriptの中に定める - Qiita
まずはCreate React Appのインストール。プロジェクト名は「css-in-js-test」にする。
$ npx create-react-app css-in-js-test
「css-in-js-test」というフォルダが作られる
フォルダに移動
$ cd css-in-js-test
Create React Appを起動
$ npm start
ブラウザのlocalhostの3000番が開く
Reactロゴがクルクル!
「Control + C」でいったん停止する。
styled-componentsインストール
次に「styled-components」をインストールする
$ npm install --save styled-components
package.jsonを確認
"dependencies": { "@testing-library/jest-dom": "^5.11.6", "@testing-library/react": "^11.2.2", "@testing-library/user-event": "^12.5.0", "react": "^17.0.1", "react-dom": "^17.0.1", "react-scripts": "4.0.1", "styled-components": "^5.2.1", // 追加! "web-vitals": "^0.2.4" },
追加された!
styled-components設定
styled-componentsをインポート
前回のCSS Modulesと同様に「App.js」で設定する。
※参考:【React】CSS ModulesでCSSとSass(SCSS)のローカルスコープを作る - クモのようにコツコツと
「App.js」の冒頭でstyled-componentsをインポートする。
import styled from 'styled-components';
styled
という名前で。
テンプレートリテラル
このような形で設定する。
const コンポーネント名 = styled.セレクタ`
プロパティ: 値;
`;
- 変数名がコンポーネント名になる
- インポート名
styled
にピリオドでセレクタをつなげる - テンプレートリテラル(` `)で囲った中にCSSの設定を書く
「テンプレートリテラル」はCSS in JS独自の書き方ではなくJSに元々ある複数行を挿入するための書き方のようだ!
テンプレートリテラルは、組み込み式を扱うことができる文字列リテラルです。複数行の文字列や文字列挿入機能を使用することができます。
※参考:テンプレートリテラル (テンプレート文字列) - JavaScript | MDN
styled-componentsを設定
このように設定してみた
const CssInJsTest = styled.p`
color: red;
`;
CssInJsTest
というコンポーネントがp
タグになる想定- 文字色を赤に
コンポーネント設定
App()
の中でCssInJsTest
コンポーネントを設定する
function App() { return ( <div className="App"> <header className="App-header"> <!-- 中略 --> <CssInJsTest> CSS in JSテストですと。 </CssInJsTest> </header> </div> ); }
中に「CSS in JSテストですと。」というテキストを入れている。
動作確認
Create React Appを起動
$ npm start
でけた!
変数を使う
プレースホルダー
次に、CSSスタイルの中に変数を使ってみたい。色やサイズなど共通化したい値はあると思うので。
変数は「プレースホルダー」を使う。
const コンポーネント名 = styled.セレクタ` プロパティ: ${変数名}; `;
「プレースホルダー」もCSS in JSの書き方ではなくJSに元々ある書き方!
テンプレートリテラルにはプレースホルダーを含めることができます。プレースホルダーはドル記号と波括弧 (${expression}) で示されます。
※参考:テンプレートリテラル (テンプレート文字列) - JavaScript | MDN
変数を設定
このように設定した。
const keyColor = 'yellow'; const CssInJsTest2 = styled.p` color: ${keyColor}; `;
- 変数
keyColor
の値をyellow
に CssInJsTest2
コンポーネントはp
タグ- 文字色を
keyColor
に
さっきとは別名のコンポーネントを新たに作った。うまくいけば文字色は黄色になるはず。
コンポーネント設定
CssInJsTest2
コンポーネントを設定
function App() { return ( <div className="App"> <header className="App-header"> <!-- 中略 --> <CssInJsTest> CSS in JSテストですと。 </CssInJsTest> <CssInJsTest2> CSS in JSテスト2ですと。 </CssInJsTest2> </header> </div> ); }
CssInJsTest
コンポーネントの下に配置。テキストは「CSS in JSテスト2ですと。」
動作確認
ブラウザを見ると
おお、黄色い文字が表示されている!!
擬似クラス(:hover)の設定
擬似クラスの書き方(&)
次に擬似クラスを設定してみる。入れ子構造で&
で繋ぐ
const コンポーネント名 = styled.セレクタ` プロパティ: 値; &:擬似クラス { プロパティ: 値; } `;
※参考:styled-components: API Reference
この入れ子構造や&
でつなぐ書き方はSass(SCSS)と同じ!
※参考:【メタ言語】BEMによるclass名をSass(SCSS)とEJSで書いてみる(モジュール事始め) - クモのようにコツコツと
擬似クラス(:hover)を設定
CssInJsTest2
に擬似クラス(:hover
)を設定する
const CssInJsTest2 = styled.p` color: ${keyColor}; &:hover { background: rgba(255,255,255,0.3); } `;
:hover
設定を&
でつなぐ- 背景色を白の不透明度30%に
動作確認
ブラウザで確認
カーソルを重ねると背景色が変わった!
子要素の設定
子要素の書き方
先ほどの擬似クラスと同じ&
で繋ぐ書き方で子要素も設定できる。
const CssInJsTest2 = styled.p` color: ${keyColor}; &:hover { background: rgba(255,255,255,0.3); } & span { font-weight: bold; } `;
:hover
の下にspan
要素の設定を追加span
要素の文字の太さをbold
に
ひと繋がりのセレクタではないのでspan
の前に半角スペースを入れている。
※参考:styled-components: API Reference
子要素を設定
function App() { return ( <div className="App"> <header className="App-header"> <!-- 中略 --> <CssInJsTest> CSS in JSテストですと。 </CssInJsTest> <CssInJsTest2> CSS in JS<span>テスト2</span>ですと。 </CssInJsTest2> </header> </div> ); }
CssInJsTest2
コンポーネントのテキスト「テスト2」をspan
タグで囲う
動作確認
ブラウザを見ると「テスト2」だけ太字になった!
コンポーネントの入れ子構造
親コンポーネントの設定
先ほどは子要素を追加したが、今度は親要素。コンポーネントの入れ子構造にしてみる。
const Block = styled.div`
margin: 20px;
padding: 0 20px;
background: #333;
border-radius: 10px;
`;
- 親コンポーネント
Block
はdiv
タグ Block
のスタイル設定(余白設定、背景は濃グレー、角丸設定)
親コンポーネントを追加
function App() { return ( <div className="App"> <header className="App-header"> <!-- 中略 --> <Block> <CssInJsTest> CSS in JSテストですと。 </CssInJsTest> <CssInJsTest2> CSS in JS<span>テスト2</span>ですと。 </CssInJsTest2> </Block> </header> </div> ); }
CssInJsTest
、CssInJsTest2
を囲う形でBlock
を配置
動作確認
ブラウザを見ると背景色が表示された!
レンダリングされたHTMLとclass名
Dev-toolsで見ると下記のHTMLがレンダリングされている。独自のclass名が振られている。
<div class="sc-bdfBwQ jeuXIP"> <p class="sc-gsTCUz wIMML">CSS in JSテストですと。</p> <p class="sc-dlfnbm eyXUGc">CSS in JS<span>テスト2</span>ですと。</p> </div>
2番目に付いているclass名がCSSと紐づいているようだ。
- Block ->
.jeuXIP
- CssInJsTest ->
.wIMML
- CssInJsTest2 ->
.eyXUGc
このランダムな文字列によってCSSがグローバルスコープになるわけか。ランダムな文字列が振られるのはCSS Modulesと同じだな。
※参考:【React】CSS ModulesでCSSとSass(SCSS)のローカルスコープを作る - クモのようにコツコツと
今回作ったソースコード全体(GitHub)
※参考:GitHub - ryo-i/css-in-js-test
最後に
ということでstyled-componentsでCSS in JSを事始めることができました。この方法は自分的には結構いい印象を受けました!
- JSXと同一ファイル内でコンポーネント名でCSSを設定できる
- JSのオブジェクト(連想配列)と違ってCSSの書式そのままで書ける
- 共通化したい値は変数として外部から読み込める
- Sass(SCSS)のようなインデントの入れ子や
&
で繋ぐ書き方ができる - 擬似クラス、擬似要素も設定できる
CSS in JSに比べるとCSS Modulesは外部ファイルを読み込むため、ちょっとコードの見通しは悪いかなー。逆にJSとCSSの設定が両方複雑で完全に別々で管理した方がいい場合はCSS Modulesの方がいいのかもしれない。
次回はUIフレームワーク「Material UI」を触ってみようと思います。
それではまた!
続き書きました!
※参考:【React】UIフレームワークMaterial UIでマテリアルデザインを事始める - クモのようにコツコツと
※参考:Reactを習得するためにやったことまとめ
qiita.com