CSS

CSS custom properties are a feature that allow you to declare variables directly in CSS and manage them dynamically, which helps improve design consistency and maintainability.

Custom Properties(カスタムプロパティ)

CSSのカスタムプロパティ(Custom Properties)とは、通称「CSS変数」と呼ばれる機能です。--変数名: 値; という形式で定義することで、CSS内で定義した値を再利用しやすくなり、デザインの一貫性やメンテナンス性が向上します。

CSS

:root {
	--main-color: #3498db; /* カスタムプロパティの定義 */
	--main-padding: 16px;
}

.content {
	color: var(--main-color); /* カスタムプロパティの呼び出し */
	padding: var(--main-padding);
}

上記の例では、--main-color--main-padding を自由に使い回すことができ、デザインを一元管理しやすくなります。

従来のプリプロセッサの変数との違い

SassやLessなどのCSSプリプロセッサを使うと、同様に変数を使うことが可能です。ただし、プリプロセッサの変数はビルド時に静的に展開されるのに対し、CSSのカスタムプロパティは実行時にブラウザが解決する動的な性質を持ちます。

メリット
JavaScriptとの連携で値をリアルタイムに変更可能。メディアクエリや要素の状態に応じてCSS変数を変化させることで、より柔軟なデザインが実現可能です。
デメリット
ブラウザのサポート状況によっては古い環境で使えない場合がある(IE11など)。

基本的な文法

定義方法

カスタムプロパティは、セレクタ内に --変数名: 値; の形で定義します。

CSS

.selector {
	--my-color: #ff0000;
	--my-size: 2rem;
}

グローバルに使いたい場合はルートセレクタ(:root)を使うことが一般的です。

CSS

:root {
	--theme-color: #3498db;
}

使い方

定義したカスタムプロパティを使う際は、var(--変数名) と書きます。

CSS

element {
	color: var(--theme-color);
}

フォールバック値

var() 関数の第2引数にフォールバック値を指定できます。カスタムプロパティが未定義または無効な場合に使用されます。

CSS

.element {
	color: var(--unknown-color, #000000); /* 未定義なら#000000を使う */
}

スコープと継承

グローバルスコープ(:root)

:root セレクタで定義されたカスタムプロパティは、基本的にどの要素からも参照可能です。サイト全体で共通のテーマカラーや余白サイズなどを管理するときに便利です。

ローカルスコープ

カスタムプロパティは、定義された要素およびその子孫要素に継承されます。

CSS

.parent {
	--local-color: #f1c40f;
}

.child {
	color: var(--local-color); /* 親の定義を継承している */
}

ただし、別の階層で再定義すると、それ以降は再定義された値が使われます。これにより、コンポーネント単位で異なるテーマを適用したり、状態(ホバーなど)によって値を変更することができます。

実践的な例

テーマ切り替え

ライトテーマ・ダークテーマなどをワンクリックで切り替えたい場合、カスタムプロパティが有効です。

CSS

:root {
	--bg-color: #ffffff;
	--text-color: #333333;
}

.dark-theme {
	--bg-color: #333333;
	--text-color: #ffffff;
}

body {
	background-color: var(--bg-color);
	color: var(--text-color);
}

JavaScriptで document.body.classList.toggle('dark-theme'); のような切り替えを行うと、一気にダークモードへ変更でき、複数箇所で使用されている色指定を同時に更新できます。

動的なサイズ変更

メディアクエリやJavaScriptでカスタムプロパティを変化させることで、フォントサイズや余白を動的に変更できます。

CSS

:root {
	--base-font-size: 16px;
}

@media (min-width: 768px) {
	:root {
		--base-font-size: 18px;
	}
}

.text {
	font-size: var(--base-font-size);
}

これにより、レスポンシブデザインでも変数を一箇所変更するだけでサイト全体のフォントサイズが整合的に変わり、管理が容易になります。

UIコンポーネントでの使い分け

ボタンなどのUIコンポーネントに、カスタムプロパティを用いることで色・余白・ボーダーなどを一括管理できます。たとえば、複数のバリエーション(プライマリ・セカンダリ・アクセントなど)を一つのコンポーネントクラスで切り替えたい場合に、カスタムプロパティが役立ちます。

CSS

.btn {
	--btn-bg: #3498db;
	--btn-color: #ffffff;
	--btn-padding: 0.5em 1em;
	
	background-color: var(--btn-bg);
	color: var(--btn-color);
	padding: var(--btn-padding);
	border: none;
	border-radius: 4px;
}

.btn--secondary {
	--btn-bg: #7f8c8d;
	--btn-color: #ecf0f1;
}

.btn--secondary では、背景色と文字色だけを上書きすることで、プライマリボタンとの差別化が可能になります。

JavaScriptとの連携

CSSカスタムプロパティは、JavaScriptから動的に値を書き換えることができます。DOM要素の style オブジェクトか、setProperty() メソッドを使って操作します。

HTML

<button id="changeTheme">テーマ変更</button>
<div class="content">...</div>

CSS

:root {
	--content-padding: 16px;
}

.content {
	padding: var(--content-padding);
}

JavaScript

document.getElementById('changeTheme').addEventListener('click', () => {
	document.documentElement.style.setProperty('--content-padding', '32px');
});

上記のように setProperty('--content-padding', '32px') を呼び出すと、即座にCSSのプロパティが更新され、ブラウザ上の要素が再描画されます。

パフォーマンスとベストプラクティス

頻繁な更新の注意点
カスタムプロパティをJavaScriptで非常に頻繁に書き換えると、再計算や再描画の負荷がかかる可能性があります。アニメーションのように高頻度で値を変更する場合には、状況に応じてtransformプロパティやrequestAnimationFrameなどを駆使しながら慎重に設計する必要があります。
名前空間の活用
大規模サイトや多数のコンポーネントを持つ場合は、変数名の衝突を防ぐために名前空間を取り入れましょう。たとえば、--color-primary--layout-main-padding のように、用途や領域を示すプレフィックスをつけると管理しやすくなります。
ネストされたテーマや状態
たとえば、.dark .header.light .header で異なるカスタムプロパティを定義することで、要素ごとのテーマを細かく制御できます。

CSS

.light .header {
	--header-bg: #f8f9fa;
}
.dark .header {
	--header-bg: #343a40;
}
.header {
	background-color: var(--header-bg);
}
これにより、同一ページ内で複数のテーマを共存させたい場合にも柔軟に対応できます。
CSSの複雑化と変数の整理
カスタムプロパティを多用すると、便利な反面、管理が煩雑になる可能性があります。どの変数がどこで定義され、どこで上書きされているかを把握しやすいように、ファイルの分割やコメント付けなど、ルールを整備して運用することが重要です。

ブラウザサポート

主要ブラウザ(最新のChrome、Firefox、Safari、Edge)はほとんどサポートしていますが、Internet Explorer 11 など古いブラウザではカスタムプロパティをサポートしていません。

もしレガシーブラウザにも対応したい場合は、PostCSSやSassなどでフォールバックを用意するか、IE11では別の手段を採用するといった対策が必要になります。

Data on support for the css-variables feature across the major browsers from caniuse.com

まとめ

CSSカスタムプロパティ(変数)の基本
メリット
注意点

追加Tips

階層的な変数設計
例えば --color-primary-lihter--color-primary-darker のように、基準となる色(--color-primary)から派生したカラーセットを構築することで、配色体系を作りやすくなります。
カスタムプロパティで計算
calc() 関数内でも var() を使えるので、動的な余白やサイズ計算を行う際に便利です。

CSS

:root {
	--base-space: 10px;
}
.container {
	padding: calc(var(--base-space) * 2);
}
トランジションとの併用
カスタムプロパティによる色やサイズの変更に対して、transition を設定すると、変化がスムーズにアニメーションします。コンポーネントごとのインタラクションをより魅力的に表現できます。

終わりに

CSSカスタムプロパティは、単なる「変数」としての使い方にとどまらず、動的で柔軟なスタイリングを可能にする重要なツールです。複雑なデザインシステムやテーマ機能を扱う際にも、コードの保守性を高めながら柔軟に拡張できる利点があります。

初めて触れる方は、まずは共通の色やフォントサイズを変数化することから始め、慣れてきたらテーマの切り替えやJavaScriptとの連携といった応用へ進むとよいでしょう。中級者以上の方は、より複雑なコンポーネント管理や名前空間設計などに取り組み、CSSカスタムプロパティを活用することで、よりスマートで再利用性の高いスタイル設計が行えます。

ぜひプロジェクトに導入して、その便利さを体感してみてください!