本記事について
当サイトを閲覧いただきありがとうございます。 本記事はシリーズ『生成AI時代のアーキテクチャ超入門』の「フロントエンドアーキテクチャ」カテゴリ第5弾として、CSS設計について解説する記事です。
CSSは書くのは簡単だが大規模化で必ず崩壊する言語。本記事ではCSS記述方式(Tailwind/CSS Modules/CSS-in-JS)の比較、デザインシステムとDesign Token、アクセシビリティ、AI時代の「Tailwind + shadcn/ui + Design Token」三点セットまで解説します。
このカテゴリの他の記事
書くのは簡単、規模化で必ず崩壊する
CSS設計の目的は、こうした崩壊を防ぎ、スタイル変更の影響範囲を限定し、デザイナーと開発者の共通言語を作ることにあります。「機能しているか」だけでなく「将来も安全に修正できるか」が品質の決め手で、規約と自動化で秩序を保つ必要があります。
CSSは楽な書き方が崩壊する書き方になりやすい。規約と自動化が命です。
主なCSS記述方式
CSSの書き方には時代とともに複数の方式が登場してきました。それぞれに哲学があり、プロジェクトの規模と好みで選びます。現代は Tailwind と CSS Modules が主流で、CSS-in-JSは衰退傾向です。
flowchart LR
GLOBAL["グローバルCSS<br/>(レガシー)"]
MOD["CSS Modules<br/>(自動ローカライズ)"]
CIJ["CSS-in-JS<br/>(styled-components)"]
TW["Tailwind CSS<br/>(ユーティリティ)"]
ZERO["ゼロランタイム<br/>Vanilla Extract / Panda"]
GLOBAL -.|スコープ問題で限界| MOD
MOD -.|動的スタイル要望| CIJ
CIJ -.|ランタイムコスト/RSC非対応| ZERO
CIJ -.|生産性で乗り換え| TW
classDef legacy fill:#fee2e2,stroke:#dc2626;
classDef stable fill:#dbeafe,stroke:#2563eb;
classDef decline fill:#fef3c7,stroke:#d97706;
classDef modern fill:#dcfce7,stroke:#16a34a;
class GLOBAL legacy;
class MOD stable;
class CIJ decline;
class TW,ZERO modern;
| 方式 | 例 |
|---|---|
| グローバルCSS | 素のCSSファイル(レガシー) |
| CSS Modules | styles.module.css(クラス名自動ローカライズ) |
| CSS-in-JS | styled-components / Emotion |
| ユーティリティCSS | Tailwind CSS(クラス羅列方式) |
| ゼロランタイムCSS-in-JS | Vanilla Extract / Panda CSS |
CSS-in-JSは一世を風靡しましたが、ランタイムオーバーヘッドと RSC(React Server Components、サーバ側で実行するReactコンポーネント)非対応の課題が指摘され、徐々にゼロランタイム方式(Vanilla Extract / Panda)やTailwindに置き換わりつつあります。
CSS Modules
CSS Modules は、ファイルごとにクラス名を自動でローカライズする仕組みです。styles.module.css と命名するだけで、ビルド時にクラス名がハッシュ化され、グローバル衝突が発生しないようになります。
/* Button.module.css */
.primary { background: indigo; color: white; }
import styles from './Button.module.css'
<button className={styles.primary}>送信</button>
長所:シンプル・学習コスト低・ランタイム負荷ゼロ・素のCSSに近い書き心地。 短所:propsで動的にスタイルを変えるのが面倒で、JSから操作が必要。
Next.js / Vite・webpackで標準サポートされており、「素のCSSに近い書き心地を保ちながら衝突を防ぎたい」時の鉄板です。
CSS-in-JS
CSS-in-JS は、JavaScriptの中にCSSを書く方式です。styled-components / Emotion が代表で、コンポーネントとスタイルを同居させられます。propsで動的にスタイルを切り替えられるなど、JSの表現力を使える点が強みです。
| 強み | 弱み |
|---|---|
| propsで動的スタイル | ランタイムオーバーヘッド |
| 型チェック可能 | RSCとの相性が悪い(サーバで動かない) |
| コンポーネント単位で完結 | バンドルサイズが増える |
ランタイム処理が入るため表示速度に影響し、React Server Componentsでは使えないため、Next.js App Router 時代には相性が悪く、徐々に廃れつつあります。2024年3月にはstyled-componentsがメンテナンスモード入りを公式発表しました。一時代を築いたOSSが静かに店じまいする典型例です。
現代はゼロランタイムCSS-in-JS(Vanilla Extract / Panda)への移行傾向が顕著です。
Tailwind CSS
Tailwind CSS は、ユーティリティクラスをHTMLに並べる方式で現代の最大潮流です。px-4 py-2 rounded bg-indigo-600 text-white のようにクラス名を羅列することでスタイルを決めます。
<button class="bg-indigo-600 text-white px-4 py-2 rounded hover:bg-indigo-700">
送信
</button>
| 強み | 弱み |
|---|---|
| 一貫性が自然に保たれる | HTMLが長くなる |
| ファイル行き来が不要 | 命名クラスの学習が必要 |
| ビルド時に未使用CSSを削除・軽量化 | 初見で読みにくい |
「HTMLが汚い」と言われがちですが、デザインシステムの値(色・間隔・フォントサイズ)が強制されるため、大規模チームで視覚的一貫性を保ちやすいのが最大の利点です。新規プロジェクトのCSS選定で「最有力候補」で、VS Codeのインテリセンス支援も充実しています。
新規プロジェクトの第一候補。デザイン一貫性と開発効率を両立できます。
ゼロランタイムCSS-in-JS
従来のCSS-in-JSの「ランタイムオーバーヘッド」を解決したのが、ゼロランタイムCSS-in-JSです。「ビルド時にCSSを抽出」してしまうため、ランタイムではCSS-in-JSの処理が走りません。
| 製品 | 備考 |
|---|---|
| Vanilla Extract | 型安全・テーマ対応・Adobe採用 |
| Panda CSS | Chakra UI系列・Design Token統合 |
| Linaria | styled-components 互換 |
| StyleX | Meta内製・Instagram等で採用 |
RSC環境で使えることが大きな強みで、Next.js App Router のようなサーバーサイドレンダリングが前提の場面で選ばれます。Vanilla Extractは「型安全性も高く」、TypeScript好きには刺さる選択肢です。
デザインシステムとDesign Token
デザインシステムとは、「再利用可能なUI部品とそれを使うルールの集合」です。GoogleのMaterial DesignやMicrosoftのFluent UIが有名で、デザインと実装を橋渡しする役割を担います。
| 要素 | 内容 |
|---|---|
| Design Token | 色・フォント・余白・影などを変数化 |
| Component | ボタン・フォーム・モーダル等の共通UI |
| Pattern | 組み合わせのベストプラクティス |
| Documentation | 使い方・原則・禁止事項 |
Design Token は、色やサイズといったデザインの値を「意味のある名前で変数化」する仕組みです。#4F46E5 ではなく color.primary と呼ぶことで、ブランド変更・ダークモード対応・テーマ切替が一括で可能になります。
❌ color: #4F46E5 ← どの色がどこで使われているか不明
✅ color: var(--color-primary) ← 意図が明確
tokens.json:
{
"color.primary": "#4F46E5",
"color.primary.dark": "#818CF8",
"spacing.sm": "8px",
"spacing.md": "16px"
}
Figma で定義したトークンをコードに取り込める Style Dictionary 等のツールが登場し、「Figma ⇔ コードでトークンを完全同期」する流れが現代の主流です。
「リブランドで滲み続けた旧色」(業界事例)
あるサービスで、リブランド(ブランドカラー変更)対応のために #4F46E5 を全ファイル置換で対応した、という話があります。コードの大半は変わりましたが、インラインスタイル・Figmaから直接コピペされたグラデーション・メール用HTMLに古い色が残り、リリース後1週間は前ブランドカラーが画面のどこかに滲み出続けた、という顛末です。
過去に似た経験で「変数化していない色はgrepで拾いきれない」という事実を身をもって学んだ、という体験談もよく聞きます。Design Tokenが最初から定義されていれば、var(--color-primary) の値を1行書き換えるだけで終わった作業でした。「ハードコードされたカラーコードは必ず後から負債になる」という典型的な教訓として語られます。
特に「デザイナーからFigmaのコピペで色を貰う」「メルマガHTMLは別チーム」のような現場では、トークンが無いと「漏れなく置換するのは事実上不可能」です。
#4F46E5 と書いた瞬間、未来の自分への借金が発生しています。
コンポーネントライブラリの選択
UIコンポーネントをゼロから作るのは時間がかかるため、既製のコンポーネントライブラリを使うのが現代の標準です。選択肢は多く、プロジェクトの色に合わせて選びます。
| ライブラリ | 特徴 |
|---|---|
| shadcn/ui | コピペ式・自分のコードになる・現代大人気 |
| Radix UI | アクセシビリティ特化・見た目なし |
| MUI(Material UI) | 最大級・独自色強い・機能豊富 |
| Chakra UI | Design Token中心・書き心地良い |
| Ant Design | 管理画面に最適・豊富な部品 |
| HeadlessUI | Tailwind前提の軽量系 |
shadcn/ui は特殊で、npmパッケージではなく「ソースコードをコピーして自分のプロジェクトに組み込む」方式です。ライブラリに依存せず自由に改変できるため、制約を嫌う開発者に支持されています。
制約少なく自分色にしたい → shadcn/ui + Radix。即戦力重視 → MUI。
アクセシビリティ(a11y)
アクセシビリティ(a11y)は、CSS設計と密接に関わる要素で、「見た目だけでなく全員が使えるUI」を作るための指標です。スクリーンリーダー利用者・キーボードのみ操作のユーザー・視覚障がい者など、多様なユーザーに配慮します。
| 原則 | 例 |
|---|---|
| 十分なコントラスト比 | 文字と背景で 4.5:1 以上 |
| フォーカス可視 | キーボードTabで移動可能 |
| セマンティックHTML | <button> を使う・<div onclick> はNG |
| ARIA(Accessible Rich Internet Applications)属性 | スクリーンリーダー用の補助情報 |
WCAG(Web Content Accessibility Guidelines、Webアクセシビリティの国際ガイドライン)2.2 AA準拠が企業サイトの現代的なラインで、政府系サイトでは「法的義務になる国も増えています」Lighthouse や axe-core で自動チェックできるため、「CIで測定する運用」が推奨されます。
CSS変数とダークモード
CSS変数(カスタムプロパティ)は、動的なテーマ切り替えの基盤技術です。:root で定義した変数を、クラスや属性で切り替えるだけでダークモード対応が実現できます。
:root {
--bg: white;
--fg: black;
}
[data-theme="dark"] {
--bg: #0b0f1e;
--fg: #e5e5e5;
}
body { background: var(--bg); color: var(--fg); }
切り替えは JS で document.documentElement.dataset.theme = 'dark' を書くだけ。Tailwindも dark: variant で同様の仕組みを標準サポートしています。OS設定を検知する prefers-color-scheme メディアクエリも組み合わせると、「OSに連動した自動切替」も実現できます。
ケース別の推奨構成
CSS設計のスタックは、プロジェクトの性質によって選択肢が変わります。現代の主流を押さえておけば、大きく外すことはありません。
- 新規SPA・中規模SaaS → Tailwind + shadcn/ui + Design Token。現代の鉄板構成
- ブログ・コンテンツサイト → 素のCSS / CSS Modules(Astroのscoped styleで十分)
- 大規模デザインシステム構築 → Vanilla Extract / Panda CSS + 自社Design Token。型安全性重視
- 既存アプリへの段階導入 → CSS Modules(局所的に導入しやすい)
- 社内管理画面 → MUI / Ant Design(部品が豊富で素早く作れる)
CSS品質の数値Gate・アクセシビリティ基準
※ 2026年4月時点の業界相場値です。テクノロジー・人材市場の変化で陳腐化するため、定期的にアップデートが必要です。
CSS設計の質は「なんとなく綺麗」ではなく数値で追うのが現代です。アクセシビリティ(WCAG 2.2 AA)準拠は「法的義務」になる国も増えています。
| 項目 | 基準値 | 理由 |
|---|---|---|
| 色のコントラスト比(本文) | 4.5:1 以上 | WCAG 2.2 AA |
| 色のコントラスト比(大きい文字) | 3:1 以上 | WCAG 2.2 AA |
| タッチ対象の最小サイズ | 44×44px | Apple HIG / WCAG |
| フォーカスリング表示 | 必須 | キーボード操作者の生命線 |
| ダークモード対応 | 推奨 | prefers-color-scheme 検知 |
| Lighthouse Accessibilityスコア | 90点以上 | 業務サイトの最低ライン |
| axe-core エラー数 | 0件 | CIで機械的にブロック |
| CSSバンドルサイズ | < 50KB(gzip後) | 1画面あたりの上限目安 |
「axe-core / Lighthouse」をCIに組み込むのが現代標準です。米国・EUではアクセシビリティ訴訟が年々増加しており、2019年の Domino’s Pizza アクセシビリティ訴訟(米国最高裁まで行き原告勝訴)以降、Webアクセシビリティは「法的リスク領域」に入りました。日本の障害者差別解消法改正(2024年4月施行)も同方向です。
WCAG 2.2 AAはCIで機械的に強制します。axe-core + Lighthouseで自動チェックです。
CSS設計の鬼門・禁じ手
CSSで事故る典型パターンを整理します。スコープ崩壊・詳細度バトル・カスケード地獄につながります。
| 禁じ手 | なぜダメか |
|---|---|
| グローバルCSSで命名規約なし | 名前衝突で「修正が怖くて触れないコード」に |
!important を多用 | 詳細度バトルの武器化。使えば使うほど解けなくなる |
インラインスタイル(style="...")を本番で使う | CSP違反・Design Token無視・修正困難 |
カラーコードをハードコード(#4F46E5 直書き) | ダークモード・リブランド時に全置換不能な領域が残る |
| CSS-in-JSをRSC環境で新規採用 | styled-componentsは2024年3月メンテ入り。Tailwind / Vanilla Extractへ |
Tailwindの @apply を多用 | Tailwindの思想を殺す。クラス羅列のまま使う |
セマンティックHTMLを無視(<div onclick> を多用) | アクセシビリティ壊滅・スクリーンリーダーで読めない |
<button> の代わりに <a href="#"> | キーボード操作・ARIAロールで破綻 |
| コントラスト比を目視だけで確認 | 4.5:1を満たさない色が大量発生。axe-coreで機械チェック必須 |
| ダークモードを後付けで実装 | カラー全箇所を変数化する大工事に。最初からDesign Token |
2019年のDomino’s Pizzaアクセシビリティ訴訟は、視覚障害者が音声読み上げでピザを注文できなかった事例で、最高裁まで行き原告勝訴。Webアクセシビリティは「気配り」ではなく「法的リスク」になっています。米国ではADA、EUではEAA(European Accessibility Act、2025年6月施行)が該当します。
カラーコード直書きは未来の自分への借金。Design Tokenから始めます。
AI時代の視点
AI駆動開発が前提になると、CSS設計は「Tailwind + shadcn/uiの独壇場」になります。UI生成AI(v0・Bolt・Lovable等)はTailwindクラス羅列を最も高精度に生成できるため、他のCSS方式と比べて圧倒的に速くUIが組めます。shadcn/uiは「コピペ方式」がAI生成と相性が良く、AIがコンポーネントの実装を直接書き換えられるのが強みです。
| AI時代に有利 | AI時代に不利 |
|---|---|
| Tailwind(AIが完璧に生成) | CSS-in-JS(RSC非対応・AI生成が不安定) |
| shadcn/ui(コピペ式・AI編集可) | 独自UIライブラリ |
| Design Token(変数で明示) | ハードコードされたカラーコード |
| ARIA属性・セマンティックHTML | <div onclick> だらけのAI生成コード |
UI生成AIの能力が爆上がりしている現代では、「Figmaデザインを貼り付けてAIに実装させる」ワークフローが個人〜中規模では実用段階に入りました。この時、生成精度はTailwind + Reactの組み合わせが頭一つ抜けている状態です。Design Tokenを事前に設定しておけば、AIがブランドカラーを無視したコードを生成することも防げます。AIはアクセシビリティ(ARIA・コントラスト)を見落としがちなので、「Lighthouse / axe-coreの自動チェックをCIに入れる」のがAI時代の補完策です。
AI時代のCSSはTailwind + shadcn/ui + Design Tokenが圧倒的に強い。他方式は明確な理由がある時だけです。
よくある勘違い
- グローバルCSSで頑張れる → 規模化すると命名衝突と詳細度バトルで「修正が怖くて触れないコード」になる。ツールでスコープを切るのが鉄板
- CSS-in-JSはモダン → RSC非対応で衰退中。styled-componentsはメンテ終了しており、新規採用は避ける
- Tailwindは汚いから避ける → HTMLが長くなるのは事実だが、「デザイン一貫性と開発速度」のリターンが圧倒的。慣れれば読めるようになる
- Design Tokenは大企業だけの話 → 個人開発でも「カラーコード直書きは後で必ず困る」変数化は最初から入れる
決めるべきこと — あなたのプロジェクトでの答えは?
以下の項目について、あなたのプロジェクトの答えを1〜2文で言語化してみてください。曖昧なまま着手すると、必ず後から「なぜそう決めたんだっけ」が問われます。
- CSS記述方式(Tailwind / CSS Modules / CSS-in-JS)
- UIコンポーネントライブラリ(shadcn/ui / MUI等)
- Design Token管理方法(tokens.json / Style Dictionary)
- 命名規約(BEM等採用時)
- アクセシビリティ基準(WCAG AA等)
- ダークモード対応(OS連動 / トグル)
- RTL(右→左記述・アラビア語等)対応
- アイコンシステム(Lucide / Heroicons等)
最終的な判断の仕方
CSS設計の核心は「グローバル崩壊を防ぐ仕組みを最初から入れる」ことです。CSSは手書き放題な言語のため、規約なしで大規模化すると命名衝突・詳細度バトル・カスケード地獄で必ず破綻します。選定の出発点は「どうスコープを分離するか」で、ツール側で解決する(CSS Modules/Tailwind/ゼロランタイムCSS-in-JS)か、命名規約で解決する(BEM等)の2択です。
「現代はツール側解決が主流」で、BEMのような命名規約で人間が頑張る必要はほぼなくなりました。もう一つの軸はDesign Tokenで、色・間隔・フォントサイズをコードで変数化することで、ブランド変更・ダークモード・テーマ切替が一発で対応できます。ハードコードされたカラーコードは後から必ず負債になります。
決定的な軸は「Tailwind + shadcn/ui + Design Token」の三点セットです。UI生成AI(v0・Bolt・Lovable)が最も高精度に書けるのがTailwind + Reactの組み合わせで、shadcn/uiのコピペ式はAIが直接コンポーネント実装を書き換えられる点で完璧に噛み合います。
CSS-in-JSはランタイムオーバーヘッドとRSC非対応で衰退傾向、CSS Modules は素のCSSに近い書き心地で手動プロジェクトには残りますが、AI駆動開発ではTailwindが圧倒的に有利です。「アクセシビリティ(WCAG 2.2 AA)はAIが見落としがちな領域」なので、Lighthouse/axe-coreをCIに入れてAIの穴を塞ぐのが補完策になります。
選定の優先順位をまとめると次の通りです。
- Tailwind + shadcn/uiを第一候補に(AI時代の圧倒的な標準)
- Design Tokenを必ず定義(ハードコード禁止)
- CSS-in-JSは避ける(RSC非対応・AI精度が落ちる)
- アクセシビリティを自動チェック(WCAG 2.2 AA + axe-core)
まとめ
本記事はCSS設計について、Tailwind/CSS Modules/CSS-in-JS・Design Token・アクセシビリティまで含めて解説しました。如何だったでしょうか。
CSSはTailwindに寄せ、Design Tokenを最初から入れる。他方式は明確な理由がある時だけ、というのが2026年の現実解です。
次回はBFF(Backend For Frontend)について解説します。
シリーズ目次に戻る → 『生成AI時代のアーキテクチャ超入門』の歩き方
それでは次の記事も閲覧いただけると幸いです。
📚 シリーズ:生成AI時代のアーキテクチャ超入門(35/89)