CSS-in-JS
JavaScript 内で CSS を記述し、コンポーネントスコープのスタイルを実現する手法
CSSフロントエンド
CSS-in-JS とは
CSS-in-JS は、JavaScript/TypeScript 内に CSS を記述し、コンポーネントごとにスコープされたスタイルを生成する手法である。グローバルな CSS の名前衝突を防止し、スタイルとコンポーネントロジックを同じファイルで管理できる。
2014 年に Christopher Chedeau (vjeux) が Facebook での CSS の課題を発表し、CSS-in-JS の流れが始まった。
主要なライブラリ
| ライブラリ | 種類 | 特徴 |
|---|---|---|
| styled-components | ランタイム | タグ付きテンプレートリテラル、動的スタイル |
| Emotion | ランタイム | styled-components 互換 + css prop |
| vanilla-extract | ゼロランタイム | TypeScript で型安全、ビルド時に CSS 生成 |
| Panda CSS | ゼロランタイム | Tailwind 的なユーティリティ + 型安全 |
| Linaria | ゼロランタイム | styled-components 的な記法、ビルド時抽出 |
ランタイム vs ゼロランタイム
// ランタイム CSS-in-JS (styled-components)
// → 実行時に <style> タグを動的に生成
const Button = styled.button<{ primary?: boolean }>`
background: ${props => props.primary ? '#007bff' : '#6c757d'};
color: white;
padding: 8px 16px;
border-radius: 4px;
`;
// ゼロランタイム CSS-in-JS (vanilla-extract)
// → ビルド時に .css ファイルを生成 (実行時コストゼロ)
export const button = style({
background: '#007bff',
color: 'white',
padding: '8px 16px',
borderRadius: '4px',
});
| 観点 | ランタイム | ゼロランタイム |
|---|---|---|
| パフォーマンス | 実行時にスタイル生成 (遅い) | ビルド時に CSS 生成 (速い) |
| 動的スタイル | props に応じて動的に変更可能 | CSS 変数で対応 |
| SSR 対応 | スタイルの抽出が必要 | 静的 CSS なので問題なし |
| バンドルサイズ | ランタイムライブラリが必要 | CSS のみ (JS 不要) |
CSS-in-JS の衰退と代替手法
2022 年頃から、ランタイム CSS-in-JS のパフォーマンス問題が広く認識され、代替手法への移行が進んでいる。
- Tailwind CSS: ユーティリティクラスで直接スタイリング。最も人気
- CSS Modules: ファイルスコープの CSS。Next.js のデフォルト
- vanilla-extract: TypeScript で型安全なゼロランタイム CSS-in-JS
- Panda CSS: Tailwind 的なユーティリティ + 型安全
React Server Components (RSC) ではランタイム CSS-in-JS が動作しないため、Next.js App Router を使う場合はゼロランタイムの手法が必須だ。
CSS-in-JS が適するケース
- デザインシステムのコンポーネントライブラリ (動的テーマ切り替え)
- props に応じて複雑にスタイルが変わるコンポーネント
- 既存の styled-components プロジェクトの保守
styled-components の例
import styled from 'styled-components';
const Button = styled.button<{ primary?: boolean }>`
background: ${props => props.primary ? '#0066cc' : '#fff'};
color: ${props => props.primary ? '#fff' : '#333'};
padding: 8px 16px;
border-radius: 4px;
`;
<Button primary>送信</Button>
CSS-in-JS の関連書籍も参考になる。