TL;DR
JavaScript や TypeScript のコードに CSS を直接書く CSS-in-JS のうち、アプリケーションの実行時にライブラリがスタイルを解釈して適用するもの。代表的なライブラリに styled-components や Emotion がある。
仕組み
コンポーネントの中で CSS を定義するので、外部の CSS ファイルに頼らずにコンポーネント単体で完結させられる。コンポーネントがレンダリングされるときに、ライブラリがスタイルを変換してドキュメントに挿入する。
注意点
実行時にスタイルを扱うため、次の問題がある。
- 実行時のオーバーヘッド: レンダリングのたびにスタイルを変換する処理が必要で、その分 CPU を使う。アプリケーションのパフォーマンスに影響することがある
- バンドルサイズの増加: ライブラリの JavaScript をダウンロードする必要がある。Emotion は 7.9 kB、styled-components は 12.7 kB ある
- デバッグのしにくさ: 内部用のコンポーネントを React のツリーに挿入するため、React DevTools が正常に動かないことがある
- ブラウザの追加作業: CSS のルールを挿入するたびに、ブラウザはそのルールが既存のツリーに当てはまるかを確かめる必要がある。React の並行レンダリングでは、レンダリング中にすべての CSS ルールとすべての DOM ノードについてスタイルの再計算が起き、パフォーマンスが大きく落ちる
- SSR やコンポーネントライブラリとの相性: Emotion を SSR や、Emotion を使う他のコンポーネントライブラリと組み合わせると、Emotion のインスタンスが複数読み込まれる、スタイルの挿入順を制御しきれない、React 17 と 18 で SSR の対応が異なる、といった問題が起きうる
これらを解決する方法として、ビルド時に CSS を生成する Zero-runtime CSS がある。