HOME
標準的なブラウザではCSSプリプロセッサを使わずに CSS変数 (CSS カスタムプロパティ) を使うことができます。CSS 変数の使い方とルール、そして calc 関数を組み合わせたときの使い方について説明します。
CSS 変数とは、正式には「カスケード変数のための CSS カスタムプロパティ (CSS custom properties for cascading variables)」と定義されています。従来の CSS では、変数は Sass や LESS のような CSS プリプロセッサを使わなければ利用できませんでしたが、多くのブラウザでサポートされたことにより利用可能になりました。ただし、Internet Explorer など一部のブラウザは対応していません。また、Edge はサポートしていますが、バグが多発している報告があるため、クロスブラウザでテストする場合は注意が必要です。もしも非対応ブラウザも含めてサポートする場合、後述する @supports
ブロックを使う方法があります。
Internet Explorer | Edge | Firefox | Chrome | Safari | Chrome for Android | Safari for iOS |
---|---|---|---|---|---|---|
✕ | ◯ | ◯ | ◯ | ◯ | ◯ | ◯ |
今まで CSS は変数が使えなかったため、サイズや色などのプロパティ値をそれぞれのセレクタに直接定義していました。そのため何かを変更するための修正コストが大きく、メンテナンス性が悪い問題点がありました。特にチーム開発など、複数人で CSS をメンテナンスしている場合、CSS 自体が破綻する原因にもなっていました。
CSS 変数は、それらの問題点を改善するための仕様です。最初に CSS 変数にプロパティ値を定義すれば、それぞれのセレクタには変数を設定するだけで値が適用されるようになります。変数を定義、および使用するルールとしては、以下のとおりです。
:root
セレクタで行う--
(ハイフン 2 つ) を付けるvar()
関数で行う:root {
--color-red: red;
}
.hoge {
color: var(--color-red);
}
var()
関数 は変数が未定義であった場合に備えて、第二引数にフォールバック値も設定できます。ただし上記の例のとおり、フォールバック値は省略が可能です。下記の例は、--color-red
が未定義である場合、blue
にフォールバックされます。
.hoge {
color: var(--color-red, blue);
}
CSS 変数には、CSS と同じようにプロパティ値を設定できるため、単位ありの数値、単位なしの数値、文字列などが設定できます。下記のようにマスターとなる値を定義しておけば、将来的に変更になった場合でも適用しているすべてのセレクタを修正する必要はなく、:root
に定義された変数のみ修正すれば良いことになります。
:root {
--def-font-size: 100 %;
--def-line-height: 1.5;
--def-background: #fff;
}
更に CSS 変数は CSS 変数を使って定義することも可能です。下記の例は、赤色と青色のグラデーションを実現するために CSS 変数を使用しています。
:root {
--color-red: red;
--color-blue: blue;
--def-gradient: linear-gradient(var(--color-red), var(--color-blue: blue));
}
CSS 変数は別の値が設定された場合、要素の子要素は新しい値を継承します。CSS は他のセレクタでも値の変更が可能であり、変更された場合は対象の要素の子要素は新しい値を継承します。これは、CSS 変数のスコープに関係しています。:root
で定義された変数はグローバルなスコープになり、他のセレクタで変更された場合は対象の要素の子要素はローカルなスコープになります。
:root {
--color-text: red;
}
.blue {
--color-text: blue;
}
p {
color: var(--color-text);
}
<p>red text</p>
<div class="blue">
<p>blue text</p>
</div>
CSS 変数は、Javascript でも getPropertyValue
を指定することで変数の値を取得できます。
.sidebar {
--left-pos: 100px;
}
// cache the element you intend to target
const sidebarElement = document.querySelector('.sidebar');
// cache styles of sidebarElement inside cssStyles
const cssStyles = getComputedStyle(sidebarElement);
// retrieve the value of the --left-pos CSS variable
const cssVal = String(cssStyles.getPropertyValue('--left-pos')).trim();
// log cssVal to print the CSS
// variable's value to the console: 100px
console.log(cssVal);
Javascript から CSS 変数の値を変更するには以下のように設定します。
sidebarElement.style.setProperty('--left-pos', '200px');
CSS 変数が非対応ブラウザを含めたクロスブラウザ対応を行う場合、@supports
ブロックを使って回避する方法があります。@supports
ブロックとは、CSS の機能をサポートしているかどうかを判別するための機能クエリです。以下の例では、非対応ブラウザが @supports
ブロックをサポートしているかどうか判別しています。また、var()
関数にフォールバック値を設定しておけば安全性が高まり、レガシーブラウザにも対応できます。以下の例で section
の要素は、CSS 変数が対応しているモダンブラウザの場合は青色文字になり、非対応のレガシーブラウザでは灰色文字になります。
section {
color: gray;
}
@supports(--css: variables) {
section {
--my-color: blue;
color: var(--my-color, 'blue');
}
}
@supports
ブロックを使った CSS 変数を設定する例CSS 変数の仕様は、あくまでも今までの問題の改善であり解決ではない点に注意してください。どのような場合においても、これらの機能に頼りすぎて複雑化すれば CSS 全体が破綻してしまうリスクはなくなっていません。CSS 変数はこれまでのメンテナンスに選択肢が増えただけに過ぎず、どのように CSS を管理していくかが重要になります。
calc()
関数とは、CSS で数学演算を行うことができる関数で、標準的なブラウザはすべてサポートしています。calc()
関数では以下のように異なる単位での四則演算が可能です。
Internet Explorer | Edge | Firefox | Chrome | Safari | Chrome for Android | Safari for iOS |
---|---|---|---|---|---|---|
△ | ◯ | ◯ | ◯ | ◯ | ◯ | ◯ |
.content {
width: calc(100% - 200px);
}
calc()
関数を使った数学演算を行う例 Sass や LESS などの CSS プリプロセッサでも値の計算は行なえますが、calc()
関数とは根本的にことなります。CSS プリプロセッサの計算された値はブラウザに依存しない静的な値であるのに対して、calc()
関数はブラウザ依存の動的な値です。つまり、画面のリサイズによって Viewport が変更されても再計算により追従することができます。もしも CSS プリプロセッサで単位の異なる値を calc()
関数として出力する場合は、以下のようになります。
/* NG */
$var: 300px;
.content {
width: calc(100% - $var); /* → width: calc(100% - $var); */
}
/* OK */
$var: 300px;
.content {
width: calc(100% - #{$var}); /* → width: calc(100% - 300px); */
}
calc()
関数を出力する例calc()
関数はサイズ、幅、高さ、角度、時間など、何かしらの単位が必要なプロパティ値に利用できます。ただし、演算子の前後はスペースで区切らなければ有効にならないため注意が必要です。
.content {
width: calc(100% - 200px); /* OK */
height: calc(100%- 200px); /* NG */
}
calc()
関数を使った数学演算を行う例calc()
関数は、特にレスポンシブデザインにおいて効果を発揮します。例えば、2 カラム構成でサブコンテンツの width
は 300px
必要で、残りはメインコンテンツにしたい場合、以下のように指定できます。
.maincontent {
width: calc(100vw - 300px);
}
.subcontent {
width: 300px;
}
calc()
関数を使った数学演算を行う例 CSS 変数と calc()
関数を組み合わせることで、より柔軟な計算ができるようになります。例えば、CSS 変数で定義した値のマイナス値が欲しい場合、以下のような方法になります。
:root {
--box-position: 100px;
}
/* NG */
.box {
top: - var(--box-position);
}
/* OK */
.box {
top: calc(-1 * var(--box-position));
}
calc()
関数を使った例 上記の方法では、CSS 変数で定義されたマイナス値を取得するために calc()
関数で -1
を掛けています。CSS 変数は少し使いにくい点はありますが、calc()
関数を組み合わせることで今まで取得できなかった値を取得できることになります。アイデア次第では CSS 変数と calc()
関数を組み合わせることで、多くのレシピを生み出すことができます。