【Web初心者向け】CSS変数(カスタムプロパティ)基礎!基本の書き方と活用例を解説

Webサイトのコーディングや更新、メディアクエリの中での書き直しが面倒。
でも、Sass (SCSS/SASS)Sを覚えたりコンパイルするのも大変だし……。

そんな時は、CSS変数を活用してみましょう。
CSS変数を使うと、CSSの値を一括で管理することが出来ます。変更があっても直す箇所が減って楽々、CSSファイル全体も見やすくなりますよ。CSS変数の使い方を解説します。

CSS変数(カスタムプロパティ)とは

CSS変数は正式には『カスケード変数のためのCSSカスタムプロパティ(CSS custom properties for cascading variables)』という、CSSのプロパティに名前をつけて呼び出せる機能です。

プログラミングでの“変数”とは少し違っているので注意が必要。
「変数感覚で扱えるプロパティ値」と言ったほうが正確な存在です。

パッと見ると、変数を設定する工程があるので、CSS変数を使うほうが面倒に思う方もいらっしゃるかもしれません。

ですが、デザインに変更があった場合。
CSS変数を使っていると、打ち替えは一箇所で済みます。

ダークモード用のCSS設定や、テーマによって配色を変えたいときも、チクチク直していかなくて良いので楽ですね。
もちろん、色だけではなく、marginなど様々なプロパティ用の設定もできます。

MDN Web Docsによると、主要なモダンブラウザは全てCSS変数対応済。

画像元:https://developer.mozilla.org/ja/docs/Web/CSS/--*

CSS量が多いWebサイトほど、CSS変数を取り入れるとコーディングの労力、更新作業の手間が省ける可能性が高いです。
SASSやSCSSよりも簡単、普段使っているcssと同じように書いていけるので、ぜひ取り入れてみましょう。

CSS変数の書き方・使い方

CSS変数の使い方基礎

1. 変数を定義する

CSS変数を使うには、まず、変数の定義が必要です。
どんな名前(変数名)で、何を記憶させたいかを決め、呼び出せるように準備します。

変数定義は下図のように、半角コロン: で区切って値を書きます。

CSSでは、変数名の冒頭に接頭辞としてハイフン2つ--が必須な点に注意してください。
CSSの変数名は、ハイフン2つから始めるのがルールと覚えておきましょう。

変数名に使えるのは、半角の英数字・アンダースコア・ハイフン。アルファベットは大文字も小文字も使えますが、別のものとして認識されます。
このあたりは id や class の命名と共通なので、普段通りでOKです。

CSS変数が使えるか、実際に試してみましょう。
以下では簡単に、HTMLファイルのhead内にCSSを書いていきます。
もちろん外部CSSファイルに書いても使えますよ。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
    <style>
        body {
            --color_main: #669900;
        }
    </style>
</head>

<body>
</body>
</html>

この時点では、CSS変数を定義しただけなので表示には何ら影響しません。
検証ツールで見ると、CSS変数の定義はできていることがわかります。

2. 呼び出す

CSS変数で設定した値を使ってみましょう。
CSS変数を利用するときにはvar() 関数というものを使います。

使い方はvar() のカッコの中に、使いたい変数名を書くだけ。

先程のHTMLファイルで、CSS変数を使って背景色を設定してみましょう。
1行付け加えます。

body {
    --color_main: #669900;
    background-color: var(--color_main);
}


ブラウザで見て、bodyの背景色が変わっていたら成功です。

CSS変数のスコープを理解する

CSS変数のスコープ

変数のスコープ(Scope)とは、変数が使える有効範囲のことです。
CSS変数に限定して言うと、スコープは普段CSSを書く時に使う“CSSセレクタ”とほぼ同じ。
例で使ってきたbody {}もCSSセレクタと一緒ですね。

変数のスコープの範囲を狭めて、例えばbg-mainクラスに限定した場合。
body要素に対するスタイル指定で、CSS変数を使っても適用されません。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
    <style>
        .bg-main {
            --color_main: #669900;
        }
        body,
        .bg-main {
            background-color: var(--color_main);
        }
    </style>
</head>
<body>
    <div class="bg-main">
        test
    </div>
</body>
</html>

ローカル変数とグローバル変数(:root)

変数のスコープによって、CSS変数を定義していても呼び出せなくなりました。
こうした限定した範囲でのみ利用できる変数をローカル変数と呼びます。反対にどこからでも利用できるようにした変数はグローバル変数と言います。

HTMLファイルの場合だと、body {}html {}でほぼ全ての要素に有効にはなります。しかし、厳密には<body>や<html>タグ内には限定されるため、これらを使って定義した変数もローカル変数として扱われます。

グローバル変数を宣言したいときは、:rootという擬似クラスを使います。
:rootはドキュメントのルート、ファイルの1番上の階層の要素を指します。HTMLファイルだとhtml {}と同じ意味になりますが、HTMLに限らずどの文書(ファイル形式)で確実にルート要素を指定できる点が違いです。

:root {
    --color_main: #669900;
}

body,
.bg-main {
    background-color: var(--color_main);
}

CSS変数のフォールバックについて

var() 関数でCSS変数を呼び出す時、フォールバックと呼ばれる代替値をセットで書くことも出来ます。「その変数がなかったら、こっちを使ってね」と予備を入れておくイメージです。

使い方は、var() の中で、変数名の後に半角コンマで区切って代替値を書くだけ。

こうすることで、指定した変数が使えない時には代替値を採用してくれます。
下図のように大文字と小文字を間違えたり、スコープから外れている場合に役立ちます。

定義されていないCSS関数を使っていることは、検証ツールでも教えてくれます。

ただ、CSS変数のフォールバックにはデメリットもあります。
MDNでは以下のように説明されています。

代替値はブラウザーの互換性を修正するためには使用されません。ブラウザーが CSS カスタムプロパティに対応していない場合、代替値は助けになりません。

この技法は変数全体を解釈するのにより時間が掛かるので、性能上の問題が見られます。

引用元:CSS カスタムプロパティ(変数)の使用 - MDN

まとめると「CSS変数非対応のブラウザでは、代替値を入れても意味がない」「ブラウザ読み込みが遅くなる」という感じ。

更に問題なのは、プロパティ値として使えない変数を指定した場合も、代替値の採用はされない点。ブラウザ側は変数が存在するか否かしか見てくれない、という場合がほとんどです。

このため、フォールバックを書かない事も多いです。
今回の色などはブラウザで確認すればすぐ分りますから、代替値の記述に手間をかけるより表示確認をしたほうが良いでしょう。

CSS変数の継承と上書き

CSS変数は、通常のCSSと同じように親要素から子要素へと継承され続けます。
:rootで指定したグローバル変数が、どこでも使えるのが代表的です。

そして、通常のスタイル指定と同じくCSS変数の値を上書きすることも可能です。
通常のCSSルール通り、上書きしたい値は、上書きしたい対象よりも下に書くようにしてください。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
    <style>
        :root {
            --color_main: #669900;
        }

        body,
        .bg-main {
            background-color: var(--color_main);
        }

        .bg-main { /* 変数を上書きする */
            --color_main: #d6ff85;
        }
    </style>
</head>
<body>
    <div class="bg-main">
        <p>
            test
        </p>
    </div>
</body>
</html>

CSS変数の活用例

CSS変数(カスタムプロパティ)はカラーコードだけでなく、数値でも文字列でも、何でも登録することが出来ます。
極端な話、プロパティ値として使えない文言でも登録自体は可能。

以下では、CSS変数を使うことで得られる恩恵が大きいものを3つ紹介します。

1. サイズ・余白にCSS変数を使う

CSS変数を活用しやすいものとして、コンテンツ幅や余白などのサイズ指定が挙げられます。
変数の定義・呼び出し方は、基本書式通りでOK。
ただし、シンプルに変数を呼び出す場合、var(--変数名) の後ろに px や % などの単位を足しても無効になります。決まった単位が必要な場合は、変数の定義時に“単位付き”にしておくのが確実。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title></title>
  <style>
    :root {
      --color_main: #669900;
      --w_content: 1200px;
      box-sizing: border-box;
    }

    .bg-main {
      background-color: var(--color_main);
    }

    .box{
      max-width: var(--w_content);
    }
  </style>
</head>
<body>
  <div class="box bg-main">
    <p>
      test
    </p>
  </div>
</body>
</html>

また、CSS変数は呼び出すだけではなく、上書きも可能でした。
この性質を活かして、以下のようにクラスごとにCSS変数を上書きすることも出来ます。CSS変数を使ってpaddingとfont-sizeを設定しているので、個別に打ち替えるよりも効率は良いでしょう。

:root {
    --color_accent: #F15A24; /* 橙 */
}
.btn{
    --btn_unit: 1rem;
    display: inline-block;
    padding: var(--btn_unit);
    background-color: var(--color_accent);
    font-size: var(--btn_unit);
    color: #FFF;
}
.btn-sm{
    --btn_unit: 0.8rem;
}
.btn-lg{
    --btn_unit: 1.4rem;
}
<div class="btn">ボタン</div>
<div class="btn btn-sm">ボタンSmall</div>
<div class="btn btn-lg">ボタンLarge</div>

検証ツールで見ると、変数が上書きされていることがわかります。

calc()と併用する

CSS変数は、四則演算ができるCSS関数calc()と組み合わせて使うことも出来ます。
変数で設定した値を元に、計算ができるわけです。

例えば、先程のボタン。
paddingを以下のように書くと、上下と左右で別の大きさにできます。

.btn{
    --btn_unit: 1rem;
    display: inline-block;
    padding: calc( var(--btn_unit) /2 )  var(--btn_unit) );
    ...

上下paddingは--btn_unitの半分、左右paddingは--btn_unitと同じ値が設定されます。
1rem=16pxなら「padding : 8px 16px; 」と書いた状態です。

btn-smやbtn-lgクラスでは--btn_unitの値を変更しました。

.btn{
    --btn_unit: 1rem;
    display: inline-block;
    padding: calc( var(--btn_unit) /2 )  var(--btn_unit) );
    background-color: var(--color_accent);
    font-size: var(--btn_unit);
    color: #FFF;
}
.btn-sm{
    --btn_unit: 0.8rem;
}
.btn-lg{
    --btn_unit: 1.4rem;
}

それぞれ変更された--btn_unitの値に合わせて、上下paddingと左右paddingも変わります。
縦横のバランスを保ったまま、自動的に余白(padding)が変わってくれるのです。

また、先ほど「シンプルに変数を呼び出す場合は単位が必要」と紹介しました。
CSS変数の方に単位が入っていない場合、calc()関数と組み合わせることで、単位を付け足してプロパティ値として使うことも可能です。

:root {
    --w_content: 1200;
}

.box{
    max-width: calc( var(--w_content) * 1px );
}


こうすれば使うには使えますが、1200は“px”単位以外で使わないですよね。
単位が固定であれば、単位込みで変数にしたほうがシンプルで良いと思います。

2. フォント指定に使う

フォント指定など「長くてわかりにくい」値をCSS変数にしておくこともあります。
見出しの一部分だけ・数字だけなど部分的にフォントを変えたい場合や、多言語対応のWebサイトを作る時にも役立つかもしれません。

簡単なコードで試してみましょう。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>フォント</title>
  <style>
    :root{
      font-family: "Helvetica Neue", "Helvetica", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Arial", "Yu Gothic", "Meiryo", sans-serif;
    }
    h1{
      font-size: 36px;
    }
    .num{
      font-size: 1.25em;
      padding-right: 0.25em;
    }
  </style>
</head>
<body>
  <h1>
    CSS Variables
  </h1>
  <p>
    CSS変数を使ってみるテストです
  </p>
  <h2>
    <span class="num">1.</span>CSS変数とは
  </h2>
  <p>
    CSS変数は、CSSのプロパティ値に好きな名前をつけて呼び出せる機能です。
  </p>
</body>
</html>

このページで、H1とH2の数字部分(numクラス)だけフォントを変えたいとします。
わかりやすように、特徴的なGoogleFont“Lobster”で試してみます。

Lobster - Google Fonts

まず、フォントファミリーの値それぞれに変数名をつけます。
font-familyプロパティの値としては、作成した変数を使います。
総称フォント「sans-serif」は最後に書いて、最低でもゴシック体表示にします。

@import url('https://fonts.googleapis.com/css2?family=Lobster&display=swap');
:root {
    --ff-default: "Helvetica Neue", "Helvetica", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Arial", "Yu Gothic", "Meiryo";
    --ff-graphical: "Lobster";
    font-family: var(--ff-default), sans-serif;
}
h1{
    font-family: var(--ff-graphical), sans-serif;
    font-size: 36px;

}
.num{
    font-family: var(--ff-graphical), sans-serif;
    font-size: 1.25em;
    padding-right: 0.25em;
}

ただ、この書き方だと、何らかの問題でGoogleフォントが読み込めない時に、h1と.numはOS/ブラウザ標準のゴシック体で表示されます。sans-serifを入れずfont-family: var(--ff-graphical) ;と書いた場合はOS/ブラウザ標準フォントです。
これは変数を使っていない場合も同様です。

Webフォントが使えない時の備えに「最低限、周囲から浮かないフォント」を設定したい場合は、"Lobster"の後に第二候補、第三候補...とフォントを書いていく必要があります。

今回のようにCSS変数を使っていれば、以下のように書くだけでOK。
見た目(変数名)でも「特殊なフォントがあって、使えなかったらサイトデフォルトのフォントにする」ということがわかります。

h1{
    font-family: var(--ff-graphical), var(--ff-default), sans-serif;
}

ちなみに、CSS変数を使わずに書くと、以下のように長くなります。

h1{
    font-family: "Lobster", "Helvetica Neue", "Helvetica", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Arial", "Yu Gothic", "Meiryo", sans-serif;
}

CSS変数で書いたものと比べると、わかりやすさでも劣るのではないでしょうか。

今回のフォント指定に限らず、ずらっと書くと長すぎてわかりにくい!という指定は結構あります。
こうしたところで、CSS変数を活用してコンパクトにする方もいらっしゃいます。

3. カラー管理・設定に使う

CSS変数を使って、使用するカラーを管理することも多いです。
あらかじめ使用するカラーを--color_mainなどの変数にしておいて、要素・クラスなどに対する色指定では変数を使います。そうすることで、変更があっても変数定義を書き換えるだけで全てに反映されます。

◆複数のCSS変数でカラーバリエーションを作る

CSS変数では、変数の定義に変数を使うこともできます。
例えば、以下のようにCSS変数を組み合わせてカラーバリエーションを作ったりも出来ます。

以下ではHSLを使って、カラーバリエーションを作ってみます。
CSSで使える色の指定方法については、下記講座でも解説しています。

早速やってみましょう。
HSLはH(色相))・S(彩度)・L(輝度)の3つの値を組み合わせ、色を指定する方法です。
--color_accentの橙色(#F15A24)を、HSLに置き換えるとHSL(16, 88%, 54%)

この数値それぞれを変数にして、変数`--color_accent`で組み立てます。

:root {
    --color_h-accent: 16;
    --color_s-9: 88%;
    --color_l-5: 54%;
    --color_accent: hsl( var(--color_h-accent), var(--color_s-9), var(--color_l-5) );
}
.bg-accent{
    background-color: var(--color_accent);
}

HTMLの方にもクラスを追加します。

<h1 class="bg-accent">
    CSS Variables
</h1>

HSLのメリットは、同じ色味で明るい・暗いのバリエーション、同一トーンのカラーバリエーションを作る時にわかりやすいこと。

例えば明るい色を作りたい場合は、Lの値を大きい数にすればできます。
明るさ(L)の値を入れる--color_l-7というCSS変数を新たに作り、色そのものを設定する変数--color_accent-lightで使います。

:root {
    --color_h-accent: 16;
    --color_s-9: 88%;
    --color_l-5: 54%;
    --color_l-7: 68%;
    --color_accent: hsl( var(--color_h-accent), var(--color_s-9), var(--color_l-5) );
    --color_accent-light: hsl( var(--color_h-accent), var(--color_s-9), var(--color_l-7) );
    --w_content: 1200px;
}

.bg-accent{
    background-color: var(--color_accent);
}
.bg-accent-light{
    background-color: var(--color_accent-light);
}
<h2 class="bg-accent-light">
    <span class="num">1.</span>CSS変数とは
</h2>

色相(H)の値を変えると、別の色で同じトーンの色が作れます。
青系=primaryとして、以下のように設定します。

:root {
    --color_h-accent: 16; /* 橙 */
    --color_h-primary: 221; /* 青 */
    --color_s-9: 88%;
    --color_l-5: 54%;
    --color_l-7: 68%;
    --color_accent: hsl( var(--color_h-accent), var(--color_s-9), var(--color_l-5) );
    --color_accent-light: hsl( var(--color_h-accent), var(--color_s-9), var(--color_l-7) );
    --color_primary: hsl( var(--color_h-primary), var(--color_s-9), var(--color_l-5) );
    --color_primary-light: hsl( var(--color_h-primary), var(--color_s-9), var(--color_l-7) );
}

.bg-primary{
    background-color: var(--color_primary);
}
.bg-primary-light{
    background-color: var(--color_primary-light);
} 
<h1 class="bg-accent">
    CSS Variables
</h1>
<p class="bg-primary">
    CSS変数を使ってみるテストです
</p>
<h2 class="bg-accent-light">
    <span class="num">1.</span>CSS変数とは
</h2>
<p class="bg-primary-light">
    CSS変数は、CSSのプロパティ値に好きな名前をつけて呼び出せる機能です。
</p>

色味・明るさが揃って見えるのではないでしょうか。

例えば、primaryのカラーが青系ではなく紫系に変更になった場合
HSLそれぞれの値をバラバラに管理している場合、--color_h-primaryの値を書き換えれば、その変数を使っているもの全てが更新されます。

/* --color_h-primary: 221; */
--color_h-primary: 280;


色の濃さでカラーバリエーションを作っていたり、:hoverなど状態に合わせて濃淡を付けていたり、という場合は、更新が楽でしょう。

とは言え、HSLやRGBの値を個別に用意する方法は、小規模なサイト、変更・更新をほぼしない場合、カラーの統一性があまりない場合は手間に見合いません。更新作業よりも、最初の準備のほうが大変……なんて場合は無理に使わなくてもよいでしょう。

こうした書き方は、大規模なサイトや、カラーテーマが複数あるようなUIを作る際に使われることもあります。色の設定方法の一つとして、頭の片隅に置いておくと、いざという時にも困らないかなと思います。

まずは無料で14講座から始めましょう!

ハイクオリティな14講座/98レッスンが受け放題。
募集人数には制限があります。サインアップはお早めに。
無料申し込み期限
5月26日まで

募集 人数
100名 (残りわずか)

こちらもオススメ

×