タイトル: hsl()、hsla()
SEOタイトル: CSS hsl()/hsla() 色指定完全ガイド(相対色・Color Functions Level 4)
| この記事の要点 |
|
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 表記早見表
| 色名 | HEX | RGB | HSL |
|---|---|---|---|
| 赤 | #ff0000 | rgb(255, 0, 0) | hsl(0 100% 50%) |
| オレンジ | #ffa500 | rgb(255, 165, 0) | hsl(39 100% 50%) |
| 黄 | #ffff00 | rgb(255, 255, 0) | hsl(60 100% 50%) |
| 緑 | #00ff00 | rgb(0, 255, 0) | hsl(120 100% 50%) |
| シアン | #00ffff | rgb(0, 255, 255) | hsl(180 100% 50%) |
| 青 | #0000ff | rgb(0, 0, 255) | hsl(240 100% 50%) |
| マゼンタ | #ff00ff | rgb(255, 0, 255) | hsl(300 100% 50%) |
| 白 | #ffffff | rgb(255, 255, 255) | hsl(0 0% 100%) |
| 黒 | #000000 | rgb(0, 0, 0) | hsl(0 0% 0%) |
| グレー | #808080 | rgb(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%); }
/* ...と続く */
ブラウザ対応
| 機能 | Chrome | Firefox | Safari |
|---|---|---|---|
| hsl() / hsla() カンマ区切り | 1+ | 3+ | 3.1+ |
| hsl() スペース区切り + / alpha | 65+ | 52+ | 12.1+ |
relative color syntax from | 119+ | 128+ | 16.4+ |
| oklch() / oklab() | 111+ | 113+ | 15.4+ |
FAQ
Q: H に deg を付けるべき?
A: 必須ではありません。hsl(0) と hsl(0deg) は同じ。明示したいなら deg。turn / rad / grad も使えます。
Q: hsl() で 純色(#ff0000 系)を表現するときの L は何 %?
A: 50%。L=100% は白、L=0% は黒です。彩度を保った最大の鮮やかさが L=50%。
Q: oklch() に切り替えるべき?
A: 新規設計なら oklch() が知覚均等で優秀。既存資産が hsl() なら無理に書き直す必要はありません。L の意味が hsl と違う(oklch の L=50% は人間の感じる中間グレー)点に注意。