アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

【CSS3】HSL色空間による色指定のすゝめ

こんにちは、橋本です。

今日は、知らない人も多いCSS3の隠れた(?)新機能、HSL色空間による色指定について書いてみたいと思います。

Webにおける色指定の方法として一番メジャーなのは、16進数を用いたRGB値による色指定の方法かと思います。

説明不要かもしればせんが、#に続けて、赤、緑、青の順に、0から255の数値を16進数を用いて色を指定する方法です。



    .hoge {
        background-color: #123456;    
    }


その他に色キーワードを用いた色指定の方法や、rgb(rgba)関数を用いた色指定の方法があります。



    .hoge {
        background-color: red;
        color: rgb(255, 255, 255);
    }


CSS3では、上記の色指定の方法に加えて、HSL色空間による色指定を行うことが可能になりました。

HSL色空間とは、色相(Hue)、彩度(Saturation)、明度(lightness)の3つの成分からなる色空間のことで、色相を0〜360度の範囲(赤を0度に置き、時計回りに赤、橙、黄、黄緑、緑、青緑、青、青紫、紫、赤紫の順に変化)で、彩度を純色から灰色の範囲で、明度を白から黒の範囲で(中間が純色)表すものです。

色相のイメージ


色相、彩度、明度の関係



色相の角度による色の把握がわかりやすく、また、色の鮮やかさや明るさを数値で指定することで増減することができるため、rgbを用いた色指定の方法よりも、直感的に色の指定が行える方法になっています。

CSS3でHSLによる色指定を行うには、hsl関数(透明度を指定する際には、hsla)を用いて指定します。
引数は、色相(0〜360までの数値)、彩度(0%〜100%)、明度(0%〜100%)の順に指定します。
(hsla関数の場合は、上記に加え、透明度を0.0〜1.0の値で指定します。)



    .hoge {
        background-color: hsl(0, 100%, 50%) // 純色の赤
        color: hsl(60, 100%, 80%) // 明るい黄色
    }


rgbによる色指定では、「ちょっと色を明るくしたい、もうちょっと赤を強くしたい」などといったときに、直感的に修正しにくいため、カラーピッカー等を用いてrgb値を確認する必要があったのですが、HSLによる色指定であれば、色相、彩度、明度を調節することで簡単に色を調節することができます。

CSS3による新機能のため、使える場面が限られるのですが、使える場合には是非使ってみていただければと思います。

ちなみに、HSLについて調べている中で、RGBからHSLに変換する変換式とHSLからRGBに変換する変換式を見つけたので、javascriptで実装してみました。

以下のサンプルページで変換を試すことができるので、ぜひ触ってみてください。

サンプル

>>JS
/**
* hslからrgbに変換する関数
*
* hue 色相。0〜360の数値を指定
* saturation 彩度 0〜100%の値を指定
* lightness 明度 0〜100%の値を指定
*/
var hslToRgb = function(hue, saturation, lightness){
var h = Number(hue),
s = Number(saturation.replace('%', '')) / 100,
l = Number(lightness.replace('%', '')) / 100,
max = l <= 0.5 ? l * (1 + s) : l * (1 - s) + s,
min = 2 * l - max,
rgb = {};

if (s == 0) {
rgb.r = rgb.g = rgb.b = l;
} else {
var list = {};

list['r'] = h >= 240 ? h - 240 : h + 120;
list['g'] = h;
list['b'] = h < 120 ? h + 240 : h - 120;

for (var key in list) {
var val = list[key],
res;

switch (true) {
case val < 60:
res = min + (max - min) * val / 60;
break;

case val < 180:
res = max;
break;

case val < 240:
res = min + (max - min) * (240 - val) / 60;
break;

case val < 360:
res = min;
break;
}

rgb[key] = res;
}
}

// CSS用に変換して返す
return 'rgb(' + Math.round(rgb.r * 255) + ',' + Math.round(rgb.g * 255) + ',' + Math.round(rgb.b * 255) + ')';
};

/**
* rgbからhslに変換する関数
*
* red 赤。0〜255の数値を指定
* green 緑。 0〜255の値を指定
* blue 青。 0〜255の値を指定
*/
var rgbToHsl = function(red, green, blue){
var r = red / 255,
g = green / 255,
b = blue / 255,
rgb = {
'r': r,
'g': g,
'b': b
},
max = Math.max(r, g, b),
min = Math.min(r, g, b),
hsl = {
'h': 0,
's': 0,
'l': (max + min) / 2
};

// 彩度と色相の算出
if (max != min) {
// 彩度
var m = hsl.l <= 0.5 ? (max + min) : (2 - max - min);
hsl.s = (max - min) / m;

// 色相
var c = {};
for (var k in rgb) {
var v = rgb[k];
c[k] = (max - v) / (max - min);
}

var h;
switch (max) {
case r:
h = c.b - c.g;
break;

case g:
h = 2 + c.r - c.b;
break;
case b:
h = 4 + c.g - c.r;
break;
}

h = h * 60;

hsl.h = h < 0 ? h + 360 : h;
}

// CSS用に変換して返す
return 'hsl(' + hsl.h + ', ' + hsl.s * 100 + '%, ' + hsl.l * 100 + '%)';
};