hsl()内でcalc()を利用し、それとCustom Propertiesを組み合わせ、色を機械的に生成するコードの例。

CSSでの色については単純な変数だけでは少し足らない。それはCustom Propertiesがあったとしても同じで、論理的に操作したいという欲求があるからだ。少し明るくしたいとか、ここはビビットにとか、補色から30度近づけたい(Triad)とか、計算できるものを計算で生成できると良いわけだ。そこで明るさや鮮やかさをベースに色を定義できるhsl()関数とcalc()関数を組み合わせ、さらにそれをCustom Propertiesを通して合成することで色を生成するというアイディアを考えた。既にChrome 54やSafari 10では実現可能だ。

Demo: Generating Colors

hsl()そのものを計算することはできないので、色相・彩度・明度をそれぞれ定義し、それを計算するという方針になる。最終的にCustom Propertiesを駆使してhsl()に合成している(本当はルールセットのコンテキストで定義を変えるだけで行いたかったが、うまくいかなかった)。デモではhsl(30, 100%, 50%)をベースに1.5倍明るい色と半分の明るさの色、そして補色を生成してみている。

簡単な例で仕組みを見てみよう。

:root {
  --lightness: 50%;
  --color-test: hsl(30, 100%, calc(var(--lightness) * 1.5));
}

.test {
  color: var(--color-test);
}

ここでは明度に絞って定義してみた。定義した明度をvar()を使って拾い、それをcalc()を使って1.5倍にするわけだ。色定義はグローバルにあった方が都合が良いと思うので、このような形でざっくりと色を定義してしまい、後で参照する方が良いだろう。


仕様としてはhsl()の中でcalc()が使えて良いのだろうか。

CSS Color Module Level 3の仕様においては残念ながら使えそうもない。理由はhsl()を構成する各要素がCSSの仕様で定義されるところの<number><percentage>ではなく、一般的な意味での数字や割合だという定義にとどまっているからだ。そしてCSS Values and Units Module Level 3calc()<number>などの代わりにはなるとだけ定義されているため、hsl()の中では使えないことになるだろう。

それではChrome 54やSafari 10が独自に実装しているのかというとそうではない。

来るCSS Color Module Level 4ではhsl()は各要素が<number><percentage>で構成されると決まりつつあるからだ。上述のようにそれらの代わりにcalc()を使えることになっているので、hsl()の中でもcalc()は使えるべきだろう。仕様への準拠度が高いとされるFirefox 49(や51)がまだそうなっていないが、単にCSS Color Level 4の実装が進んでいないだけと考えられそうだ。

未実装のブラウザーのイシューを探したところ、相当するイシューは立てられているようなので、そのうち使える方向で統一されるはずだ。


Sassの色関数からの脱却を図るためにhsl()関数を使うようにメンタルを調教している過程で発見した。Sassを捨てる準備が確実に進んでいる。