CSS の新機能

作成日:2018年10月9日

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

カスタムプロパティは、CSS のユーザー定義変数で、CSS 変数と呼ばれることもあります(以降では CSS 変数と呼ぶことにします)。公式には「CSS Custom Properties for Cascading Variables」と呼ばれています。

CSS Custom Properties for Cascading Variables Module Level 1 (W3C)

CSS 変数が使えると、とても便利になりますが、残念ながら IE11 は対応していません。

caniuse CSS Variables(ブラウザ対応状況)

Sass などのプリプロセッサーでは変数が使えますが、プリプロセッサーの変数は CSS にコンパイルしなければなりません。対して、CSS 変数は、ブラウザーで実行する動的な CSS プロパティです。また、CSS 変数は、JavaScript コードから直接アクセスすることができます。

変数の宣言と使用

CSS 変数(カスタムプロパティ)は先頭にハイフンを2つ付けて任意の名前を記述し、通常の CSS プロパティと同じようにコロンで区切って値を記述します。

.foo {
  --my-bg-color: yellow;
}   

定義した CSS 変数を呼び出すには、使用したい箇所で var() 関数を使います。

.foo {
  background-color: var(--my-bg-color);
}

CSS 変数のスコープは CSS セレクタ内になりますが、:root 擬似クラスに定義してグローバル変数のように使用することができます。

つまり、:root 擬似クラスで変数を宣言することで、変数を CSS 内のどこでも使用することが可能です(html 要素内の全てに適用することができます)。

:root {
  --main-bg-color: #efefef;
  --main-text-color: #999;
}
  
.foo {
  background-color: var(--main-bg-color);
  color: var(--main-text-color);
  width: 100px;
  height: 50px;
}
  
.bar {
  background-color: var(--main-bg-color);
  color: var(--main-text-color);
  width: 200px;
  height: 100px;
}

注意点

  • CSS 変数では大文字と小文字が区別されます。
  • プロパティ名を変数にすることはできません(値のみが変数として利用可能)。
  • CSS 変数はカスケードの対象となります。

CSS 変数の中で CSS 変数を設定

CSS 変数の値に別の CSS 変数を設定することもできます。

以下は、グラデーションを CSS 変数を使って設定する例です。グラデーションの CSS 変数の値には、開始色(--start-color)と終了色(--end-color)の CSS 変数を使っています。

:root {
  --start-color: #C7F9D8;
  --end-color: #9FB0F2;
  --bg-gradient: linear-gradient(var(--start-color), var(--end-color));
}
.foo {
  background: var(--bg-gradient);
  width: 100px;
  height: 100px;
}
<div class="foo"></div>

CSS 変数の継承

通常の CSS プロパティと同じように、CSS 変数は継承されます。

class="three" の div 要素は、親要素(class="bar")の値を継承します。

<div class="bar">
  <p>abcdefg</p>
  <div class="one">
    <p>abcdefg</p>
  </div>
  <div class="two">
    <p>abcdefg</p>
  </div>
  <div class="three">
    <p>abcdefg</p>
  </div>
</div>
:root {
  --main-color: blue;
}
.bar p {
  color: var(--main-color);
}
.one {
  --main-color: red;
}
.two {
  --main-color: green;
}

abcdefg

abcdefg

abcdefg

abcdefg

メディアクエリ内で CSS 変数を使う

Sass の変数はメディアクエリ内で動作しませんが、CSS 変数は機能します。

:root {
  --my-bg: #EEE;
}
@media (max-width: 580px) {
  :root {
    --my-bg: green;
  }
}
.buz {
  background: var(--my-bg);
  height: 50px;
  border: 1px solid #CCC;
  line-height: 50px;
}

以下の div 要素は、幅が580px以下で背景色が緑色に変わります。

class="buz"

参考サイト:僕がネイティブな CSS 変数にわくわくする理由

フォールバックの指定

CSS 変数にはフォールバック(代替値)の値を1つ以上設定することができます。

var() 関数を使用して、指定された変数が定義されていない場合や無効な場合の代替値をカンマで区切って複数指定することができます。

以下の場合、--my-var が定義されていなければ green が適用されます。

.foo {
  color: var(--my-var, green); 
}

以下の場合、 --my-var が定義されていなければ --my-var2 が適用されます。

.foox {
  color: var(--my-var, var(--my-var2)); 
  
  /* 以下は NG。CSS 変数を指定する場合、var() 関数を使用する必要があります。 */
  color: var(--my-var, --my-var2); /* ※--my-var2 は適用されない */
}

以下の場合、 --my-var が定義されていなければ --my-var2 が適用され、 my-var 及び --my-var2 が定義されていなければ red が適用されます。

.foo {
  color: var(--my-var, var(--my-var2, red)); 
}

但し、フォールバックの指定は、パフォーマンスに影響があるようです。以下は「MDN CSS のカスタムプロパティ (変数) の利用」からの引用です。

このテクニックはパフォーマンスの問題を起こすことがあります。変数を解釈するのにより時間が掛かるため、ブラウザーがページを表示するのが通常よりも遅くなります。

JavaScript で CSS 変数を使用

CSS 変数は、JavaScript から直接アクセスすることができます。

.foo クラスの CSS 変数 --bg-gradient が以下のように設定されている場合、JavaScript で --bg-gradient の値を取得できます。

:root {
 --start-color: #C7F9D8;
 --end-color: #9FB0F2;
 --bg-gradient: linear-gradient(var(--start-color), var(--end-color));
}
#foo {
  background: var(--bg-gradient);
  width: 100px;
  height: 100px;
  margin: 20px 0;
}

#foo の計算済みスタイルを getComputedStyle() で取得して、getPropertyValue() で変数の値を取得します。

// #foo の計算済みスタイルを取得 
const fooStyle = getComputedStyle(document.getElementById("foo"));

// CSS 変数 --bg-gradient の値の取得 
const fooVal = fooStyle.getPropertyValue('--bg-gradient'); 
//または const fooVal = String(fooStyles.getPropertyValue('--bg-gradient')).trim();

console.log(fooVal); //出力:linear-gradient( #C7F9D8,  #9FB0F2)

JavaScript で CSS 変数の値を変更する場合は setProperty() を使います。

document.getElementById("foo").style.setProperty('--bg-gradient', 'linear-gradient( #CCCCCC,  #333333)');