CSSカスタムプロパティでデザイン変数を一元管理する|現場で使える実践テクニック
こんにちは!
今日は「CSSカスタムプロパティでデザイン変数を一元管理する」についてお話しします。
僕が色管理で失敗した話
正直に告白するんですけど、僕も過去に色の管理めっちゃ失敗したんです。
昔のプロジェクトで、ボタンの色を#3b79b7って直書きしちゃってて、全部で30箇所ぐらいに散らばってたんですよ。
そしたらクライアントから「色をもうちょっと濃くしてほしい」って言われて…もう大変でした。
30箇所全部を検索と置換で修正する羽目になって、その過程でうっかり背景色まで変わってしまったり、本当にカオスでしたね。
その時に「あ、これ変数化しときゃよかったな」って痛感したんです。
それからはCSSカスタムプロパティを積極的に使うようになって、今は現場でも後輩たちに推奨してるんですよ。
実際に使い始めるとほんま効率が全然違います。
CSSカスタムプロパティの基本的な使い方
では、CSSカスタムプロパティの基本から説明しますね。
カスタムプロパティは、CSS内で変数として機能するもので、--で始まる名前を付けます。
最もシンプルな例を見てみましょう。
:root {
--primary-color: #3b79b7;
--secondary-color: #5a9fd4;
--spacing-unit: 8px;
}
button {
background-color: var(--primary-color);
padding: var(--spacing-unit) calc(var(--spacing-unit) * 2);
}
.alert {
color: var(--primary-color);
border: 1px solid var(--secondary-color);
}
:rootセレクタで定義した変数は、ページ全体で使えます。var()関数で呼び出すだけです。
これだけでもすごく便利なんですけど、さらに便利なのが「スコープ付きで上書き」できることです。
:root {
--primary-color: #3b79b7;
}
.dark-mode {
--primary-color: #ffffff;
}
button {
background-color: var(--primary-color);
}
こうすると、.dark-modeクラスが付いた要素の中では、ボタンの背景色が白になるんです。
ダークモード対応とか、複数のテーマを持つサイトでめっちゃ活躍しますよ。
実際の現場で活躍するデザイン変数の設計
ここからは、実際に現場で見かけるデザイン変数の設計パターンをお話しします。
初心者の方も、これを参考にするといい構成ができると思います。
カラーシステムの構築
色の管理が最も重要です。
プライマリ、セカンダリといった基本色だけでなく、状態別の色も一緒に管理するといいですよ。
:root {
/* ブランドカラー */
--color-primary: #3b79b7;
--color-secondary: #5a9fd4;
--color-accent: #ff6b35;
/* 状態別の色 */
--color-success: #10b981;
--color-warning: #f59e0b;
--color-error: #ef4444;
--color-info: #0ea5e9;
/* ニュートラルカラー */
--color-bg-primary: #ffffff;
--color-bg-secondary: #f9fafb;
--color-text-primary: #1f2937;
--color-text-secondary: #6b7280;
--color-border: #e5e7eb;
}
これだけあれば、ほぼすべての色設定に対応できます。
スペーシングスケールの構築
余白の管理も重要です。
8pxを基準にした倍数で設定すると、デザインに統一感が出ます。
:root {
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
--spacing-2xl: 48px;
}
.card {
padding: var(--spacing-lg);
margin-bottom: var(--spacing-md);
}
.card-title {
margin-bottom: var(--spacing-sm);
}
タイポグラフィ変数の活用
フォントサイズや行高さも変数化すると、レスポンシブ対応がめっちゃやりやすくなります。
:root {
--font-family-base: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--font-size-xs: 12px;
--font-size-sm: 14px;
--font-size-base: 16px;
--font-size-lg: 18px;
--font-size-xl: 24px;
--line-height-tight: 1.25;
--line-height-normal: 1.5;
--line-height-relaxed: 1.75;
}
h1 {
font-size: var(--font-size-xl);
line-height: var(--line-height-tight);
}
p {
font-size: var(--font-size-base);
line-height: var(--line-height-normal);
}
レスポンシブ対応での上書き
ここが現場あるあるなんですけど、モバイルでは違う余白にしたいとか、ありますよね。
そういう時も変数の上書きが便利です。
:root {
--spacing-lg: 24px;
--font-size-xl: 24px;
}
@media (max-width: 768px) {
:root {
--spacing-lg: 16px;
--font-size-xl: 20px;
}
}
.card {
padding: var(--spacing-lg);
/* モバイルではpaddingが自動的に16pxに変わる */
}
これほんま便利なんです。
メディアクエリの中で一箇所だけ変数を上書きすれば、その変数を使ってるすべての要素に反映されます。
フォールバック値の設定
まれに変数が定義されてないケースがあるので、フォールバック値を設定しておくといいですよ。
button {
background-color: var(--primary-color, #3b