メインコンテンツへ移動

HEXをHSLに変換

「HEXからHSLへの変換」は、hexカラーコードを色相・彩度・輝度に変換します。3つのチャンネルを0–1にスケールし、その最大値と最小値から答えを導きます。輝度は両者の中点、彩度は両者の開き具合、色相はどのチャンネルが最大か、そしてどれだけ差があるかで決まります。結果は正確で可逆です。ただしHSLの輝度は、目が報じる明るさではありません。その上に何かを築く前に知っておくべき点です。

端末内で処理
HEX の入力

左側に色を入力してください。# の有無を問わない16進数の値、 rgb(), hsl(), oklch() および CSS の色名に対応しています。

HEXをHSLに変換はどう動きますか?

HSLは、同じ3バイトに対する別の座標系です。各チャンネルを0–1にスケールし、最大と最小を見つければ、あとは自動的に決まります。輝度は両者の中点、chromaはその差、色相はどのチャンネルが最大か、残りの2つがそれに対してどう位置するかで決まります。

色相の数値はどこから来るか

色相環は6つの60°セクターに分かれ、1つずつが原色と二次色に対応します。赤が最大のチャンネルなら赤のセクターにいて、その中での位置は、緑が青に対してどれだけ先行または後れるかで決まります。#ff8800では、赤が最大、緑が0.533、青が0なので、色相は(0.533 − 0) / 1 × 60 = 32°です。今まで見てきたどの色相計算も、これをよりコンパクトに書いたものです。

彩度は相対的な値で、人を驚かせる

同じchromaでも、輝度によって彩度の数値は変わります。分母が変わるからです。式はchroma / (1 − |2L − 1|)です。非常に暗い色や非常に明るい色はchromaの余地が少ないため、チャンネル間の小さな絶対差が高い彩度として報告されます。#010200が彩度100%で返ってくるのはこのためです。ほぼ黒の色であり、その輝度で可能な範囲では、これ以上ないほど色づいているのです。

HSLの輝度は知覚的な明るさではない

ここが持って帰るべき論点です。hsl(60 100% 50%)は黄色、hsl(240 100% 50%)は青で、HSL上はどちらも輝度50%です。しかし目には、一方はほぼ白、他方はほぼ黒に見えます。この式は3つのチャンネルを等しく重み付けしますが、目はそうしません。緑は知覚的な明るさに、青の約10倍寄与します。

実用上の帰結はこうです。HSLの輝度を段階させて作ったtintランプは、数値がどれだけ均等でも見た目の段差が不均等になり、HSLの色相を回して作ったパレットは、眩しすぎる色と見えなくなる色が混ざって出てきます。値がランプ、ミックス、明るさに関する判断に使われるなら、OKLCHを使ってください。下の出力にも含まれており、現在のすべてのブラウザがCSSで受け付けます。

hexカラーコード

#ff8800

色相・彩度・輝度

hsl(32 100% 50%)

max  255 / 255 = 1.000   (red)
min    0 / 255 = 0.000   (blue)
lightness = (1 + 0) / 2 = 50%
chroma    = 1 − 0 = 1.000 → saturation 100%

HEXをHSLに変換が対応するオプションとエッジケースは?

技術リファレンスとオプション
パラメータ型デフォルト動作とエッジケース
色相0–360deg0 = 赤ホイール上の位置。120は緑、240は青。ラップされるため、370と10は同じです。
彩度0–100%—その明度で許容される最も高い彩度に対する相対的な彩度。0%は任意の色相での灰色です。
明度0–100%—0%はすべての色相で黒、100%は白です。50%で色相が最も彩度を持ちます。
アルファ0–11現代的な構文ではスラッシュの後に記述されます: hsl(32 100% 50% / 50%)。
hsl()とhsla()—同一hsl()は現在アルファを取ります。hsla()はレガシーエイリアスで、非推奨ではありません。
グレーS = 0—彩度がない場合、色相は任意であり情報を持ちません。ここではノイズではなく0として報告されます。
ラウンドトリップ正確—HexからHSLに、そして戻すと同じ色が返されます。この式は近似ではなく、座標系の変換です。
OKLCH代替—同じ考え方——色相角、彩度、明度——ですが、目が報告するものと一致する明度軸を持っています。

よくある質問

手作業でhexをHSLに変換するには?

hexを3つの0–255チャンネルに変換し、それぞれを255で割って、最大値と最小値を取ります。輝度は(max + min) / 2です。chromaはmax − minで、0なら灰色なのでこれで終わりです。そうでなければ彩度はchroma / (1 − |2L − 1|)で、色相は最大だったチャンネルから求まります。赤なら((G − B) / chroma) × 60、緑なら((B − R) / chroma + 2) × 60、青なら((R − G) / chroma + 4) × 60です。

ほぼ黒の色が彩度100%になるのはなぜですか?

HSLの彩度は絶対値ではなく、その輝度で取りうる最大chromaに対する相対値だからです。輝度1%ではchromaの余地がほとんどなく、チャンネル間のわずかな差が、その輝度で許される限りは最大に色づいた状態になります。つまり100%と報告されるのです。正しく動作しています。ただ、測っているものが、多くの人が期待するものとは別だというだけです。

HSLの輝度は明るさと同じですか?

違います。ここに罠があります。HSLは3つのチャンネルを等しく重み付けしますが、目は青より緑をはるかに重く見ます。hsl(60 100% 50%)とhsl(240 100% 50%)は同じ輝度を名乗りますが、一方は眩しい黄色、他方はほぼ黒です。知覚的な明るさに依存するもの——tintスケール、コントラストの判断、ミックス——には、HSLがもっともらしい誤答を返す場所で、OKLCHが正しい答えを返します。

CSSでHSLを使うべきですか?

得意なことなら適材です。色相を少しずらす、彩度を落とす、一目で読める色を書く、といった用途には問題ありません。スケールの生成や2色の補間には間違った道具です。輝度軸が知覚的でないためです。その種の仕事には、現在のすべてのブラウザが対応しているoklch()を使ってください。

hexからHSLへの変換で精度は落ちますか?

変換そのものは正確です。同じ3バイト上の座標変換にすぎません。精度を落とすのは表示です。色相を1度単位、彩度を0.1%単位に丸めると、元のhexとまったく同じには戻らないことがあります。このページの値は往復できる精度で表示しており、保証された完全な往復が必要ならhexのまま持ってください。

色相をずらさずに色を明るくしたり暗くしたりするには?

HSLに変換して、輝度だけを動かします。色相と彩度を固定したまま輝度を50%、60%、70%と段階させるのが、1つの色として読めるtintスケールを作る方法です。hexを手でいじってもこれはできません。3つのチャンネルに同じ値を加えると、明るさだけでなく色相も変わってしまうからです。