oklch と新しい色の関数

Baseline 2023〜2026oklch を土台に、元の色から明るさや透明度を変えた色や、読みやすい文字色を作るMDN ↗

STEP 1

これまでは rgb か hsl

これまでの CSS では、色を rgb か hsl で指定してきました。下のスライダーで色を選んでみてください。

hsl は色相を回すだけで色を選べるので扱いやすい形です。

rgb(58 91 217)
hsl(228 68% 54%)

STEP 2

hsl は明るさがそろわない

色相(h)だけを 30 度ずつ変えた 12 色です。明度の数値は全部同じなのに、黄色や水色は明るく、青や紫は暗く見えます。

灰色の行の見方

それぞれの色を白黒にしたときの明るさ(0〜100)です。hsl では色相によってばらつきます。

hsl(h 100% 60%)
  • 0
  • 30
  • 60
  • 90
  • 120
  • 150
  • 180
  • 210
  • 240
  • 270
  • 300
  • 330

STEP 3

oklch なら明るさがそろう

同じ数値を oklch の明るさに入れると、灰色の行がすべて同じ明るさになります。oklch は人の目に見える明るさに近い尺度で色を決めるからです。

l
明るさ(0% = 黒、100% = 白)
c
鮮やかさ(0 で灰色)
h
色相(0〜360 度)
oklch(60% 0.15 h)
  • 0
  • 30
  • 60
  • 90
  • 120
  • 150
  • 180
  • 210
  • 240
  • 270
  • 300
  • 330

STEP 1

元の色から色を作る

oklch(from 元の色 l c h) と書くと、元の色を l・c・h に分解できます。l・c・h を calc() で計算し直すと、明るさや鮮やかさを変えた色が作れます。

元の色を変えると、ほかの色もすべて一緒に変わります。

  • 元の色
  • 明るく
  • 暗く
  • くすませる
  • 反対の色相
  • 半透明

STEP 2

ボタンの状態の色を作る

ボタンのホバー・押し込み・フォーカス・無効の色を、元の色 1 つから作れます。transition を付ければ色の変化がアニメーションになります。

試し方

ボタンにマウスを乗せる・押す・Tab キーでフォーカスを当ててみてください。STEP 1 で元の色を変えると、ボタンの色も変わります。

  • #fef3c7
  • #22d3ee
  • #e11d48
  • #4ade80
  • #1e3a8a
  • #111827

使っている機能

rgb(r g b)
赤・緑・青の光の量(0〜255)で色を指定する
hsl(h s l)
色相(0〜360度)・彩度・明度で色を指定する。明度が同じでも、色相によって見た目の明るさが変わる
oklch(l c h)
明るさ(l)・鮮やかさ(c)・色相(h)で色を指定する。人の目に見える明るさに近い尺度なので、色相を変えても明るさがそろう(Baseline 2023)

CSS

/* l(明るさ)と c(鮮やかさ)をそろえて、h(色相)だけを変える */
.oklch-oklch .oklch-color {
	background: oklch(var(--l) 0.15 var(--h));
}

使っている機能

oklch(from …)
相対カラー構文。元の色を l・c・h に分解し、calc() で計算し直した色を作る(Baseline 2024)
alpha(from … / 0.4)
元の色の透明度だけを変える(Baseline 2026)

CSS

/* from で元の色を分解し、l・c・h を計算し直して新しい色を作る */
.relative-lighter {
	background: oklch(from var(--base) calc(l + 0.2) c h);
}

.relative-darker {
	background: oklch(from var(--base) calc(l - 0.2) c h);
}

.relative-muted {
	background: oklch(from var(--base) l calc(c * 0.3) h);
}

.relative-complement {
	background: oklch(from var(--base) l c calc(h + 180));
}

/* 透明度だけを変える */
.relative-alpha {
	--alpha-color: alpha(from var(--base) / 0.4);
}

/* ボタンの状態ごとの色を、元の色 1 つから作る */
.relative-button {
	background: var(--base);
	transition: background-color 0.2s, box-shadow 0.2s, scale 0.1s;
}

.relative-button:hover {
	background: oklch(from var(--base) calc(l + 0.08) c h);
}

.relative-button:active {
	background: oklch(from var(--base) calc(l - 0.1) c h);
	scale: 0.96;
}

.relative-button:focus-visible {
	box-shadow: 0 0 0 4px alpha(from var(--base) / 0.4);
}

.relative-button:disabled {
	background: oklch(from var(--base) calc(l + 0.15) calc(c * 0.3) h);
}

使っている機能

contrast-color()
背景色に対して読みやすい文字色を、白か黒から自動で選ぶ(Baseline 2026)

CSS

/* 背景色に対して読みやすい文字色(白か黒)を自動で選ぶ */
:is(.contrast-button, .contrast-list li) {
	background: var(--bg);
	color: contrast-color(var(--bg));
}

HTML

<button type="button" class="contrast-button" style="--bg: #fde047">購入する</button>