2.

CSS hsl()/hsla() 色指定完全ガイド(相対色・Color Functions Level 4)

編集
この記事の要点
  • hsl(H, S%, L%): H=色相 (Hue) 0-360 度、S=彩度 (Saturation) 0-100%、L=明度 (Lightness) 0-100%
  • hsla(H, S%, L%, A): A=アルファ 0-1(透明度)
  • CSS Color 4 の新区切り: hsl(0 100% 50%) / hsl(0 100% 50% / 0.5)(カンマ無し、スラッシュで alpha)
  • 相対色(Relative Color Syntax): hsl(from var(--c) h s calc(l * 0.8)) で明度だけ調整
  • HEX/RGB と比べ 色の調整(明るく/暗く・彩度を抑える)が直感的 → デザイントークン設計に向く

hsl() / hsla() の基本構文

CSS の hsl() 関数は色相 (Hue)、彩度 (Saturation)、明度 (Lightness) の 3 軸で色を指定します。人間の感覚に近い軸なので、「もう少し明るく」「彩度を抑えて」といった調整がコード上で直感的に行えます。

/* 旧形式(カンマ区切り) */
.a { color: hsl(0, 100%, 50%); }        /* 赤 */
.b { color: hsl(120, 100%, 50%); }      /* 緑 */
.c { color: hsl(240, 100%, 50%); }      /* 青 */

/* alpha 付き */
.d { color: hsla(0, 100%, 50%, 0.5); }  /* 半透明の赤 */

/* CSS Color 4(新形式・カンマなし・スラッシュで alpha) */
.e { color: hsl(0 100% 50%); }
.f { color: hsl(0 100% 50% / 0.5); }
.g { color: hsl(0 100% 50% / 50%); }    /* % でも書ける */

/* H に単位を付けてもよい */
.h { color: hsl(0deg 100% 50%); }
.i { color: hsl(0turn 100% 50%); }      /* 0turn = 0deg */
.j { color: hsl(3.14rad 100% 50%); }

3 つの軸の意味

範囲意味
H (Hue) 色相0-360 度0=赤 / 60=黄 / 120=緑 / 180=シアン / 240=青 / 300=マゼンタ / 360=赤
S (Saturation) 彩度0-100%0%=グレースケール / 100%=最大彩度(鮮やか)
L (Lightness) 明度0-100%0%=完全黒 / 50%=純色 / 100%=完全白
A (Alpha) 透明度0-1 or 0-100%0=完全透明 / 1=完全不透明

主要色の HSL 表記早見表

色名HEXRGBHSL
#ff0000rgb(255, 0, 0)hsl(0 100% 50%)
オレンジ#ffa500rgb(255, 165, 0)hsl(39 100% 50%)
#ffff00rgb(255, 255, 0)hsl(60 100% 50%)
#00ff00rgb(0, 255, 0)hsl(120 100% 50%)
シアン#00ffffrgb(0, 255, 255)hsl(180 100% 50%)
#0000ffrgb(0, 0, 255)hsl(240 100% 50%)
マゼンタ#ff00ffrgb(255, 0, 255)hsl(300 100% 50%)
#ffffffrgb(255, 255, 255)hsl(0 0% 100%)
#000000rgb(0, 0, 0)hsl(0 0% 0%)
グレー#808080rgb(128, 128, 128)hsl(0 0% 50%)

HSL の強み: 色の調整が直感的

HEX/RGB だと「青を 20% 明るく」は計算しないと書けませんが、HSL なら L を変えるだけです:

/* 基準色 */
.base   { background: hsl(210 90% 50%); }   /* 鮮やかな青 */

/* 明度違い(lighter / darker) */
.lighter { background: hsl(210 90% 70%); }  /* L を +20% */
.darker  { background: hsl(210 90% 30%); }  /* L を -20% */

/* 彩度を抑える(落ち着いた色) */
.muted   { background: hsl(210 30% 50%); }

/* 色相を回す(補色) */
.complementary { background: hsl(30 90% 50%); }  /* 210 + 180 = 390 = 30 */

/* 全部グレースケール */
.gray    { background: hsl(0 0% 50%); }     /* S を 0% に */

CSS Custom Property + HSL で themable な設計

:root {
  /* 色相だけ変数化、明度・彩度はバリアントで決める */
  --brand-hue: 210;
  --brand-saturation: 90%;
}

.btn-primary {
  background: hsl(var(--brand-hue) var(--brand-saturation) 50%);
}
.btn-primary:hover {
  background: hsl(var(--brand-hue) var(--brand-saturation) 40%);  /* 少し暗く */
}
.btn-primary:disabled {
  background: hsl(var(--brand-hue) 20% 70%);                       /* 彩度落として明るく */
}

/* ダークモード */
@media (prefers-color-scheme: dark) {
  .btn-primary { background: hsl(var(--brand-hue) var(--brand-saturation) 60%); }
}

CSS Color Functions Level 4: 相対色(Relative HSL)

2024 年から主要ブラウザで使えるようになった Relative Color Syntax。既存の色を分解して新しい色を作れます:

:root {
  --c: hsl(210 90% 50%);
}

/* h/s/l キーワードで元色の各成分にアクセスできる */
.hover  { background: hsl(from var(--c) h s calc(l - 10%)); }
.muted  { background: hsl(from var(--c) h calc(s - 40%) l); }
.tint   { background: hsl(from var(--c) h s 90%); }
.alpha  { background: hsl(from var(--c) h s l / 0.5); }

/* HEX を HSL 経由で alpha 付きに変換 */
.card {
  background: hsl(from #3b82f6 h s l / 0.1);
}

HSL から HEX/RGB への変換

// HSL を 0-255 RGB に変換するアルゴリズム
function hslToRgb(h, s, l) {
  s /= 100;
  l /= 100;
  const k = (n) => (n + h / 30) % 12;
  const a = s * Math.min(l, 1 - l);
  const f = (n) => l - a * Math.max(-1, Math.min(k(n) - 3, 9 - k(n), 1));
  return [
    Math.round(f(0) * 255),
    Math.round(f(8) * 255),
    Math.round(f(4) * 255),
  ];
}

const [r, g, b] = hslToRgb(210, 90, 50);
const hex = '#' + [r, g, b].map(v => v.toString(16).padStart(2, '0')).join('');
console.log(hex);  // #1a83f0 付近

ブラウザ DevTools の色ピッカーは HEX ↔ RGB ↔ HSL の切り替えに対応しています。CSS で書いた hsl() をクリックしてHEX に切り替えて確認するのが実用的です。

hsl() vs rgb() vs HEX の使い分け

形式向いている用途欠点
HEX (#fff)デザインカンプの色固定、SVG/メール計算で調整できない、alpha は #ffffffff(8桁)が必要
rgb()画像処理、Canvas、色合成明るさ・彩度の調整が直感的でない
hsl()テーマカラー設計、ホバー/無効状態、ダークモード知覚均等ではない(青の L=50% と黄の L=50% は明るさが違って見える)
oklch() / oklab()本格的な広色域・知覚均等カラー、最新デザインシステム2023 年以降のブラウザのみ、慣れが必要

ダークモードでの活用例

:root {
  --bg-h: 220;
  --bg-s: 15%;
}

/* ライトモード: L が高い → 明るい背景 */
body {
  background: hsl(var(--bg-h) var(--bg-s) 98%);
  color:      hsl(var(--bg-h) var(--bg-s) 10%);
}

/* ダークモード: L を逆転 */
@media (prefers-color-scheme: dark) {
  body {
    background: hsl(var(--bg-h) var(--bg-s) 8%);
    color:      hsl(var(--bg-h) var(--bg-s) 90%);
  }
}

/* グレースケールのバリエーション */
.bg-50  { background: hsl(var(--bg-h) var(--bg-s) 98%); }
.bg-100 { background: hsl(var(--bg-h) var(--bg-s) 95%); }
.bg-200 { background: hsl(var(--bg-h) var(--bg-s) 90%); }
.bg-300 { background: hsl(var(--bg-h) var(--bg-s) 80%); }
/* ...と続く */

ブラウザ対応

機能ChromeFirefoxSafari
hsl() / hsla() カンマ区切り1+3+3.1+
hsl() スペース区切り + / alpha65+52+12.1+
relative color syntax from119+128+16.4+
oklch() / oklab()111+113+15.4+

FAQ

Q: H に deg を付けるべき?
A: 必須ではありません。hsl(0)hsl(0deg) は同じ。明示したいなら degturn / rad / grad も使えます。

Q: hsl() で 純色(#ff0000 系)を表現するときの L は何 %?
A: 50%。L=100% は白、L=0% は黒です。彩度を保った最大の鮮やかさが L=50%。

Q: oklch() に切り替えるべき?
A: 新規設計なら oklch() が知覚均等で優秀。既存資産が hsl() なら無理に書き直す必要はありません。L の意味が hsl と違う(oklch の L=50% は人間の感じる中間グレー)点に注意。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. rgb()、rgba()
  2. hsl()、hsla()

最近更新/作成されたページ