本文へスキップ
App Museum
お気に入りEnglish

HSLとHSV(HSB)の違いと使い分け、CSSでの変換方法

FigmaやPhotoshopのHSB(HSV)値をCSSのHSLにそのまま指定すると色がずれる理由、明度(L)と輝度(V)の計算の違い、相互変換の計算式と使い分けを解説します。

公開日

HSLとHSV(HSB)の違い

FigmaやPhotoshopなどのデザインツールで調べたHSB(HSV)の数値をCSSの hsl() にそのまま入力すると、意図した色と大きくかけ離れた薄い色や白になってしまいます。このずれが生じる根本的な理由は、HSLの「L(Lightness / 明度)」とHSVの「V(Value / 明度・明暗)」、そして両者の「S(Saturation / 彩度)」の計算基準がまったく異なるためです。HSVでは「V=100%, S=100%」が最も鮮やかな純色を表すのに対し、HSLでは「L=100%」は常に完全な白を表し、純色は「L=50%」のときに位置します。

なお、デザイン分野で広く使われる「HSB(Hue, Saturation, Brightness)」と、画像処理や工学で使われる「HSV(Hue, Saturation, Value)」は、用語が異なるだけで計算式や値の定義はまったく同じものです(B = V)。

色空間の立体モデルで理解する(円錐と双円錐)

HSLとHSVの違いは、色空間を立体的な形状として捉えると直感的に理解できます。

HSVの立体モデル(円錐・円柱)

HSVは、単一の円錐(または円柱)としてモデル化されます。

  • 底辺の中心(または頂点): 黒(V = 0%)
  • 上面の中心: 白(V = 100%, S = 0%)
  • 上面の外周: 最も鮮やかな純色(V = 100%, S = 100%)

HSVでは「光の強さ(RGBの最大値)」をそのまま V と定義しています。そのため、赤(#ff0000)のVは100%であり、白(#ffffff)のVも100%です。色相環の最も鮮やかな色が天井(上面の外周)に並び、そこから白に向かって彩度Sが下がり、底に向かって明度Vが落ちて黒になります。

HSLの立体モデル(双円錐)

一方、HSLは上下に向かい合った2つの円錐を合わせた「双円錐(または円柱)」としてモデル化されます。

  • 最下端の頂点: 完全な黒(L = 0%)
  • 最上端の頂点: 完全な白(L = 100%)
  • 中央(赤道)の外周: 最も鮮やかな純色(L = 50%, S = 100%)

HSLでは「白と黒の中間」に純色を配置しています。Lが50%を超えると、どんな色相・彩度であっても徐々に白に近づいていき、L=100%になると彩度Sの値にかかわらず必ず真っ白になります。デザインツールで「B = 100%」だったからといってCSSに hsl(..., ..., 100%) と書いてしまうと、純色ではなく純白が表示されてしまうのはこのためです。

彩度(S)の違い:同じ色でもSの値が一致しない理由

明度(LとV)の違いだけでなく、彩度(S)の定義も両者で異なります。

  • HSVの彩度(Sv): その色に含まれるRGB成分のうち、最大値と最小値の差を最大値で割った割合(純色の純度)です。
  • HSLの彩度(Sl): その明るさ(L)において取り得る最大の鮮やかさに対する割合です。

そのため、同じ色であってもHSVの彩度とHSLの彩度は一致しません。代表的な色の比較は次のとおりです。

  • 純色の赤(#ff0000): HSV 0°, 100%, 100%/HSL 0°, 100%, 50%。HSLのLは50%になる
  • 純白(#ffffff): HSV 0°, 0%, 100%/HSL 0°, 0%, 100%。HSLではL=100%で白
  • トマト色(#ff6347): HSV 9°, 72%, 100%/HSL 9°, 100%, 64%。HSVはSが72%、HSLはSが100%
  • 鮮やかな青(#3b82f6): HSV 217°, 76%, 96%/HSL 217°, 91%, 60%。HSLのほうがSが高くLが低い
  • 暗い紺色(#0f172a): HSV 222°, 64%, 16%/HSL 222°, 47%, 11%。暗い色でもLとVに差が出る

このように、トマト色(#ff6347)ではHSVの彩度が72%なのに対し、HSLの彩度は100%になります。色相(H)だけは両者で共通(0〜360度)ですが、SとL/Vはそのまま流用できません。

HSLとHSVの相互変換の計算式

RGB値を介さずに、HSVとHSLを直接相互に変換する計算式は次のとおりです。各値は0〜1の小数として計算します。

HSVからHSLへの変換式

HSVの値(H, Sv, V)からHSLの値(H, Sl, L)を求める式:

L = V * (1 - Sv / 2)

Sl(HSLの彩度)は、L の値によって次のように求めます:

  • L = 0 または L = 1 のとき: Sl = 0
  • それ以外のとき:
    Sl = (V - L) / min(L, 1 - L)
    

HSLからHSVへの変換式

HSLの値(H, Sl, L)からHSVの値(H, Sv, V)を求める式:

V = L + Sl * min(L, 1 - L)

Sv(HSVの彩度)は、V の値によって次のように求めます:

  • V = 0 のとき: Sv = 0
  • それ以外のとき:
    Sv = 2 * (1 - L / V)
    

色相 H は、どちらの変換でもそのまま同じ値を使用します。

デザインツールとWeb実装(CSS)での使い分け

なぜデザインツールとWeb標準で異なる方式が使われているのでしょうか。それぞれの得意分野を理解すると、使い分けの判断が明確になります。

なぜデザインツール(Figma・Photoshop)はHSBを使うのか

グラフィックデザインやUIデザインの作業では、色の「陰影」や「ハイライト」を直感的に探す必要があります。 HSBの2次元ピッカー(横軸に彩度、縦軸に明度)では、右上に最も鮮やかな純色が配置され、下に向かって影(黒の混入)、左に向かって淡さ(白の混入)が展開されるため、絵の具や自然界の光の当たり方に近い感覚で色を選びやすいという利点があります。

なぜCSSはHSL(およびOKLCH)を採用したのか

Webのコーディング(CSS)では、「基本色に対してホバー時に少し暗くする」「アクティブ時に少し明るくする」といった色バリエーションをパラメータ操作で生成する場面が多くあります。 HSLであれば、hsl(210, 80%, 50%) の基本色に対して、明度だけを下げた hsl(210, 80%, 40%) でホバー時の暗いボタン色を作ることができます。

なお、CSSには hsv() や hsb() 関数はありません。hsv(...) と書いても無効な値として無視されます。HSBの値をCSSで使うには、HEX・RGB・HSL・OKLCHに変換するか、CSS Color Module Level 4 の hwb()(Hue, Whiteness, Blackness)で書きます。hwb() はHSVと同じ考え方の表し方で、色相はそのままに、白さを W = (1 - Sv) × V、黒さを B = 1 - V で換算できます。たとえばHSBで「9°, 72%, 100%」のトマト色は hwb(9 28% 0%) です。

また、HSLにも「同じL=50%であっても、黄色は明るく見え、青は暗く見える」という人間の視覚特性(知覚的な明るさ)とのずれという弱点があります。現代のCSS(CSS Color Module Level 4)では、この弱点を解決し知覚的な均一性を備えた oklch() が広くサポートされています。

カラーコード変換ツールで確かめる

App Museumのカラーコード変換ツールは、HEX・RGB・HSLのいずれかを入力すると、HSV(HSB)・CMYK・OKLCHの表記も並べて表示します。HSVを直接入力する欄はないので、デザインツールからはHEXの値をコピーして入れます。表示されたHSVの値がデザインツールのHSBと合っているかを見比べ、そのまま hsl() や oklch() の表記をコピーできます。この色を背景にしたときの文字色とのコントラスト比(WCAG 2)も同じ画面で確かめられます。

参考資料

開発者向けcolorcsshslhsvhsb