CSS Variables を使うと CSS で変数のようなカスタムプロパティを使うことができる仕様で Chrome 49 から使えるようになっています。
:root {
--foreground: black;
--background: white;
}
:root * {
color: var(--foreground);
background-color: var(--background);
}
div {
--foreground: red;
--background: green;
}
このように書くとページ全体では白地に黒文字、 <div>
のなかでは緑地に赤文字になります。
--foreground
や --background
が CSS Variables なのですが、これらの値を JavaScript からも触ることができます。
取得
DOM の style
プロパティからは style="..."
で指定した値を取得できます。ただし普通のスタイルのように style.color
のようにプロパティからは取得できず、 getPropertyValue()
メソッドを使います。
<div id="a" style="--a: xyz"></div>
<script>
console.log(document.querySelector('#a').style.getPropertyValue('--a')); // "xyz"
</script>
実際に適用されている値はさらに getComputedStyle()
メソッドと組み合わせると取得できます。
<style>
#b { --x: blue !important; }
</style>
<div id="b" style="--x: red"></div>
<script>
console.log(document.defaultView.getComputedStyle(document.querySelector('#b')).style.getPropertyValue('--a')); // "blue"
</script>
値の設定
値の取得が getPropertyValue
なら設定は setPropertyValue
だと考えるのが自然ですが、実際はsetProperty
です。
<div id="c" style="--x: 1"></div>
<script>
document.querySelector('#c').style.setProperty('--x', 2); // 書き換え
</script>
応用
JavaScript から CSS に値を渡せるのが確認できたので、それを活用した例を考えてみます。
<!DOCTYPE html>
<meta charset="utf-8">
<style>
:root {
width: 100%;
height: 100%;
--scroll: 0;
}
#a {
background: gray;
height: 3000px;
width: calc(100% * var(--scroll));
}
</style>
<div id="a">a</div>
<script>
window.addEventListener('scroll', () => {
const root = document.documentElement;
const body = document.body;
root.style.setProperty('--scroll',
body.scrollTop / (body.scrollHeight - root.offsetHeight));
}, false);
</script>
scroll
イベントでスクロール率を計算して CSS に渡しています。その値を使って div
要素の width
を計算しています。実際に表示するとスクロールに連動して幅がうねうね動くのがわかります。
div
要素の width
を直接代入するのと違い、はじめに CSS を書けば scroll
イベントのリスナでいろいろ計算する必要がないのがメリットです。 JavaScript よりも CSS の calc()
のなかだと calc(100px + 1em)
のような計算が簡単にできるので、細かい調整が楽に済みます。
CSS Variables がすべてのブラウザで使える状況ではないので Web サイトで使うのは難しいかもしれませんが、もし使えるなら覚えておいて活用したい機能だと感じました。