本記事について
当サイトを閲覧いただきありがとうございます。 本記事はシリーズ『生成AI時代のアーキテクチャ超入門』の「フロントエンドアーキテクチャ」カテゴリ第5弾として、CSS設計について解説する記事です。
CSSは書くのは簡単だが大規模化で必ず崩壊する言語。本記事ではCSS記述方式(Tailwind/CSS Modules/CSS-in-JS)の比較、デザインシステムとDesign Token、アクセシビリティ、AI時代の「Tailwind + shadcn/ui + Design Token」三点セットまで解説します。
本記事のテーマについてさらに詳しく知りたい方は『データ視覚化のデザイン』も参考にしてみてください。
そもそもCSS設計とは何か
CSS設計とは、ざっくり言えば「Webページの見た目を定義するCSSを、チームで安全に管理し続けるためのルールを決めること」です。
洋服の収納を想像してください。1人暮らしなら引き出しに適当に入れても困りません。しかし家族が増えると、誰かがTシャツの引き出しにコートを詰め込み、別の誰かが自分の服が見つからず新しく買ってしまう──CSS設計もこれと同じで、小規模なら問題ないグローバルなスタイル定義が、大規模化すると名前の衝突・意図しない上書き・不要スタイルの山積みという崩壊を起こします。
なぜCSS設計が重要なのか
もしCSS設計なしで大規模開発したらどうなるか。書くのは簡単だが規模化で必ず崩壊するのがCSSの本質です。スタイル変更の影響範囲を限定し、デザイナーと開発者の共通言語を作るのがCSS設計の目的です。
「機能しているか」だけでなく「将来も安全に修正できるか」が品質の決め手で、規約と自動化で秩序を保つ必要があります。
主なCSS記述方式
CSSの書き方には時代とともに複数の方式が登場してきました。それぞれに哲学があり、プロジェクトの規模と好みで選びます。現代は Tailwind と CSS Modules が主流で、CSS-in-JSは衰退傾向です。
| 方式 | 例 | 向くケース |
|---|---|---|
| グローバルCSS | 素のCSSファイル(レガシー) | 小規模・個人ブログ |
| CSS Modules | styles.module.css(クラス名自動ローカライズ) | 既存アプリへの段階導入 |
| CSS-in-JS | styled-components / Emotion | 動的スタイル多用の既存SPA |
| ユーティリティCSS | Tailwind CSS(クラス羅列方式) | 新規SPA・チーム開発全般 |
| ゼロランタイムCSS-in-JS | Vanilla Extract / Panda CSS | RSC環境・型安全重視の大規模 |
CSS-in-JSは一世を風靡しましたが、ランタイムオーバーヘッドと RSC非対応の課題が指摘され、徐々にゼロランタイム方式(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)属性 | スクリーンリーダー用の補助情報 |
WCAG2.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で命名規約なし | 名前衝突で「修正が怖くて触れないコード」に |
!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 |
| 「Tailwindは汚いから避ける」と敬遠 | デザイン一貫性と開発速度のリターンが圧倒的。慣れれば読める |
| 「Design Tokenは大企業だけの話」と思い込む | 個人でもカラーコード直書きは後で必ず困る。最初から変数化 |
2019年のDomino’s Pizzaアクセシビリティ訴訟は、視覚障害者が音声読み上げでピザを注文できなかった事例で、最高裁まで行き原告勝訴。Webアクセシビリティは「気配り」ではなく「法的リスク」になっています。米国ではADA、EUではEAA(European Accessibility Act、2025年6月施行)が該当します。
カラーコード直書きは未来の自分への借金。Design Tokenから始めます。
AI判断軸
| AI時代に有利 | AI時代に不利 |
|---|---|
| Tailwind(AIが完璧に生成) | CSS-in-JS(RSC非対応・AI生成が不安定) |
| shadcn/ui(コピペ式・AI編集可) | 独自UIライブラリ |
| Design Token(変数で明示) | ハードコードされたカラーコード |
| ARIA属性・セマンティックHTML | <div onclick> だらけのAI生成コード |
- Tailwind + shadcn/uiを第一候補に(AI時代の圧倒的な標準)
- Design Tokenを必ず定義(ハードコード禁止)
- CSS-in-JSは避ける(RSC非対応・AI精度が落ちる)
- アクセシビリティを自動チェック(WCAG 2.2 AA + axe-core)
TailwindがAI生成で圧倒的に有利な理由
TailwindのユーティリティクラスはHTMLに直接書かれるため、AIはコンポーネントのJSX内で見た目の意図を一目で把握できます。className="flex items-center gap-4 p-6 rounded-lg bg-white shadow"のような記述は、AIにとって「中央揃え・余白・角丸・白背景・影付き」という意味が即座に読み取れるためです。
CSS Modulesやstyled-componentsでは、スタイル定義が別ファイルや別関数にあり、AIがJSXとスタイルの対応を取るためのコンテキストが増えます。この差がAI生成速度と精度に直結します。
shadcn/uiのコピペ方式がAI編集を容易にする
shadcn/uiはnode_modulesにコンポーネントを隠すのではなく、プロジェクトのcomponents/ui/にコピーして使う方式です。AIにとってはプロジェクト内のファイルとしてコンポーネントの中身が見えるため、カスタマイズの指示が通りやすいです。「Buttonコンポーネントにローディングスピナーを追加して」のような指示に対し、AIはファイルを直接編集できます。
決めるべきこと — 自分のプロジェクトでの答えは?
以下の項目について、自分のプロジェクトの答えを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等)
この記事に関連する記事
https://senkohome.com/arch-intro-frontend-bff/ https://senkohome.com/arch-intro-frontend-framework/ https://senkohome.com/arch-intro-frontend-overview/
まとめ
本記事はCSS設計について、Tailwind/CSS Modules/CSS-in-JS・Design Token・アクセシビリティまで含めて解説しました。如何だったでしょうか。
CSSはTailwindに寄せ、Design Tokenを最初から入れる。他方式は明確な理由がある時だけ、というのが2026年の現実解です。
次回はBFFについて解説します。
シリーズ目次に戻る → 『生成AI時代のアーキテクチャ超入門』の歩き方
本記事で扱った内容の詳細は Tailwind CSS も合わせて参考にしてください。
それでは次の記事も閲覧いただけると幸いです。
📚 シリーズ:生成AI時代のアーキテクチャ超入門(35/89)
