Tailwind CSS や TypeScript を日常的に使っていると、色指定もrgba()やhsl()から次のステップに進みたくなる瞬間があります。 最近、CSS Color Module Level 4で追加されたoklch()は、まさにその“次の色空間”です。
この記事では、
をまとめていきます。
OKLCHとは?
OKLCHはOklab色空間の円筒(LCH)表現で、Lightness(明度)・Chroma(彩度)・Hue(色相)の3つで色を表現します。
OKLCHグラデーションの特徴
例えばgreen → redのグラデーション を作るとき、従来のrgba()やhsl()では濁ったり、明度が不自然に変化することがありました。
しかしOKLCHは知覚的に均一なので、
✅ 不自然な濁りが発生しない
✅ 明度が均一に変化する
✅ 色相の変化が滑らか
というメリットがあります。
RGBAとOKLCHのグラデーション比較
See the Pen gradient by MOYORiNO (@MOYORiNO) on CodePen.
「従来と同じ見た目のグラデーション」を作りたい場合 → OKLAB
OKLCH は知覚的に均一で便利ですが、 「今までの RGB グラデーションと同じ見た目にしたい」 というケースもあります。
その場合は OKLAB を使うと、 RGB に近い色変化を保ちながら、より滑らかに補間できます。
See the Pen Untitled by MOYORiNO (@MOYORiNO) on CodePen.
OKLCHのブラウザ対応状況
主要ブラウザはすべて対応済み(IE を除く)。
| ブラウザ | OKLCH サポート |
|---|---|
| Chrome | 対応 |
| Edge | 対応 |
| Safari | 対応 |
| Firefox | 対応 |
| Opera | 対応 |
| iOS Safari | 対応 |
| Android Chrome | 対応 |
| Samsung Internet | 対応 |
| IE | 非対応 |
Tailwind CSSでOKLCHを使う
Tailwind CSS 3.3以降では、任意のCSS関数をそのままcolorとして指定可能です。
<div class="bg-[oklch(59.69%_0.156_149.82)]">
OKLCH Color
</div>
グラデーションも同様:
<div class="bg-[linear-gradient(to_right,oklch(59.69%_0.156_149.82),oklch(59.69%_0.156_29.23))]">
OKLCH Gradient
</div>
Tailwind CSS用OKLCHカラーパレット生成ツール
以下はブラウザで動く簡易ツールのコードです。
HTML
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>OKLCH Tailwind Palette Generator</title>
<style>
body {
font-family: sans-serif;
padding: 24px;
max-width: 720px;
margin: auto;
}
.color-box {
width: 100%;
height: 40px;
border-radius: 6px;
margin-bottom: 8px;
}
textarea {
width: 100%;
height: 200px;
margin-top: 16px;
font-family: monospace;
}
</style>
</head>
<body>
<h1>OKLCH Tailwind Palette Generator</h1>
<label>Hue(色相)</label>
<input id="hue" type="number" value="120" min="0" max="360" />
<label>Chroma(彩度)</label>
<input id="chroma" type="number" value="0.15" step="0.01" />
<button id="generate">Generate Palette</button>
<div id="preview"></div>
<h2>Tailwind Config</h2>
<textarea id="output"></textarea>
<script type="module" src="/main.ts"></script>
</body>
</html>
TypeScript
function oklch(l: number, c: number, h: number) {
return `oklch(${l}% ${c} ${h})`;
}
function generatePalette(hue: number, chroma: number) {
const steps = [95, 90, 80, 70, 60, 50, 40, 30, 20, 15];
return steps.reduce((acc, lightness, i) => {
acc[(i + 1) * 100] = oklch(lightness, chroma, hue);
return acc;
}, {} as Record<string, string>);
}
document.getElementById("generate")!.addEventListener("click", () => {
const hue = Number((document.getElementById("hue") as HTMLInputElement).value);
const chroma = Number(
(document.getElementById("chroma") as HTMLInputElement).value
);
const palette = generatePalette(hue, chroma);
// プレビュー描画
const preview = document.getElementById("preview")!;
preview.innerHTML = "";
Object.entries(palette).forEach(([key, value]) => {
const div = document.createElement("div");
div.className = "color-box";
div.style.background = value;
div.textContent = `${key}: ${value}`;
preview.appendChild(div);
});
// Tailwind config 出力
const output = document.getElementById("output") as HTMLTextAreaElement;
output.value = JSON.stringify(palette, null, 2);
});