oklab()

Baseline 2023
新推出

自 ⁨2023 年 5 月⁩起,此功能可在最新的裝置和瀏覽器版本上使用。此功能可能無法在舊版裝置或瀏覽器上使用。

函式符 oklab() 在 Oklab 顏色空間中表示給定的顏色,該顏色空間試圖模仿人眼感知顏色的方式。

Oklab 是一個感知顏色空間,可用於:

  • 將影像轉換為灰度,而不改變其亮度。
  • 修改顏色的飽和度,同時保持使用者對色相和亮度的感知。
  • 建立平滑均勻的顏色漸變(例如,在 <canvas> 元素中手動插值時)。

oklab() 在 Oklab 顏色空間中使用笛卡爾座標系——a 軸和 b 軸。它可以表示比 RGB 更廣泛的顏色範圍,包括寬色域和 P3 顏色。如果你想要一個使用色度和色相的極座標顏色系統,請使用 oklch()

語法

css
/* Absolute values */
oklab(40.1% 0.1143 0.045);
oklab(59.69% 0.1007 0.1191);
oklab(59.69% 0.1007 0.1191 / 0.5);

/* Relative values */
oklab(from green l a b / 0.5)
oklab(from #123456 calc(l + 0.1) a b / calc(alpha * 0.9))
oklab(from hsl(180 100% 50%) calc(l - 0.1) a b)

下面描述了絕對顏色和相對顏色的允許值。

絕對值語法

oklab(L a b[ / A])

引數如下:

L

一個介於 01 之間的 <number>,一個介於 0%100% 之間的 <percentage>,或關鍵字 none(在此情況下等同於 0%)。此值指定顏色的感知亮度。數字 0 對應 0%(黑色),數字 1 對應 100%(白色)。

a

一個介於 -0.40.4 之間的 <number>,一個介於 -100%100% 之間的 <percentage>,或關鍵字 none(在此情況下等同於 0%)。此值指定顏色沿 Oklab 顏色空間中 a 軸的距離,該軸定義了顏色的綠色程度(朝 -0.4 移動)或紅色程度(朝 +0.4 移動)。請注意,這些值是有符號的(允許正值和負值)並且理論上是無界的,這意味著你可以設定超出 ±0.4±100%)限制的值。在實踐中,值不能超過 ±0.5

b

一個介於 -0.40.4 之間的 <number>,一個介於 -100%100% 之間的 <percentage>,或關鍵字 none(在此情況下等同於 0%)。此值指定顏色沿 Oklab 顏色空間中 b 軸的距離,該軸定義了顏色的藍色程度(朝 -0.4 移動)或黃色程度(朝 +0.4 移動)。請注意,這些值是有符號的(允許正值和負值)並且理論上是無界的,這意味著你可以設定超出 ±0.4±100%)限制的值。在實踐中,值不能超過 ±0.5

A 可選

一個 <alpha-value>,表示顏色的 alpha 通道值,其中數字 0 對應 0%(完全透明),1 對應 100%(完全不透明)。此外,關鍵字 none 可用於明確指定無 alpha 通道。如果未明確指定 A 通道值,則預設為 100%。如果包含該值,則其前面需要有一個斜槓(/)。

備註:有關 none 的效果,請參閱缺失的顏色分量

相對值語法

oklab(from <color> L a b[ / A])

引數如下:

from <color>

在定義相對顏色時,總是包含關鍵字 from,其後跟著一個 <color> 值,表示源顏色。這是相對顏色所基於的原始顏色。源顏色可以是任何有效的 <color> 語法,包括另一個相對顏色。

L

一個介於 01 之間的 <number>,一個介於 0%100% 之間的 <percentage>,或關鍵字 none(在此情況下等同於 0%)。此值表示輸出顏色的亮度。數字 0 對應 0%(黑色),數字 1 對應 100%(白色)。

a

一個介於 -0.40.4 之間的 <number>,一個介於 -100%100% 之間的 <percentage>,或關鍵字 none(在此情況下等同於 0%)。此值表示輸出顏色沿 Oklab 顏色空間中 a 軸的距離,該軸定義了顏色的綠色程度(朝 -0.4 移動)或紅色程度(朝 +0.4 移動)。請注意,這些值是有符號的(允許正值和負值)並且理論上是無界的,這意味著你可以設定超出 ±0.4±100%)限制的值。在實踐中,值不能超過 ±0.5

b

一個介於 -0.40.4 之間的 <number>,一個介於 -100%100% 之間的 <percentage>,或關鍵字 none(在此情況下等同於 0%)。此值表示輸出顏色沿 Oklab 顏色空間中 b 軸的距離,該軸定義了顏色的藍色程度(朝 -0.4 移動)或黃色程度(朝 +0.4 移動)。請注意,這些值是有符號的(允許正值和負值)並且理論上是無界的,這意味著你可以設定超出 ±0.4±100%)限制的值。在實踐中,值不能超過 ±0.5

A 可選

一個 <alpha-value>,表示輸出顏色的 alpha 通道值,其中數字 0 對應 0%(完全透明),1 對應 100%(完全不透明)。此外,關鍵字 none 可用於明確指定無 alpha 通道。如果未明確指定 A 通道值,則預設為源顏色的 alpha 通道值。如果包含該值,則其前面需要有一個斜槓(/)。

定義相對顏色輸出通道分量

oklab() 函式內部使用相對顏色語法時,瀏覽器會將源顏色轉換為等效的 Oklab 顏色(如果尚未指定)。顏色被定義為三個不同的顏色通道值——l(亮度)、a(綠/紅軸)和 b(藍/黃軸)——外加一個 alpha 通道值(alpha)。這些通道值在函式內部可用,用於定義輸出顏色的通道值。

  • l 通道值解析為一個介於 01(含)之間的 <number>
  • ab 通道各自解析為一個介於 -0.40.4(含)之間的 <number>
  • alpha 通道值解析為一個介於 01(含)之間的 <number>

在定義相對顏色時,輸出顏色的不同通道可以用幾種不同的方式表示。下面,我們將透過一些示例來說明這些方式。

在下面的前兩個示例中,我們使用了相對顏色語法。然而,第一個示例輸出的顏色與源顏色相同,第二個示例輸出的顏色則完全不基於源顏色。它們並沒有真正建立相對顏色!你不太可能在真實的程式碼庫中使用這些,而是可能會直接使用絕對顏色值。我們包含這些示例是為了讓你初步瞭解相對 oklab() 語法。

讓我們從源顏色 hsl(0 100% 50%)(等同於 red)開始。以下函式輸出與源顏色相同的顏色——它使用源顏色的 lab 通道值(0.6279660.224880.125859)作為輸出通道值。

css
oklab(from hsl(0 100% 50%) l a b)

此函式的輸出顏色為 oklab(0.627966 0.22488 0.125859)

下一個函式對輸出顏色的通道值使用絕對值,輸出了一個完全不同於源顏色的新顏色:

css
oklab(from hsl(0 100% 50%) 42.1% 0.165 -0.101)

在上述情況下,輸出顏色為 oklab(0.421 0.165 -0.101)

以下函式建立了一個基於源顏色的相對顏色:

css
oklab(from hsl(0 100% 50%) l -0.3 b)

此示例:

  • hsl() 源顏色轉換為等效的 oklab() 顏色——oklab(0.627966 0.22488 0.125859)
  • 將輸出顏色的 Lb 通道值設定為源 oklab() 等效顏色的 Lb 通道值——這些值分別為 0.6279660.125859
  • 將輸出顏色的 a 通道值設定為一個不基於源顏色的新值:-0.3

最終輸出的顏色是 oklab(0.627966 -0.3 0.125859)

備註:如上所述,如果輸出顏色使用的顏色模型與源顏色不同,源顏色會在後臺被轉換為與輸出顏色相同的模型,以便能夠以相容的方式表示(即使用相同的通道)。

在本節我們目前看到的示例中,源顏色和輸出顏色的 alpha 通道都沒有被明確指定。當未指定輸出顏色的 alpha 通道時,它預設為與源顏色 alpha 通道相同的值。當未指定源顏色的 alpha 通道時(且它不是相對顏色),它預設為 1。因此,上述示例中的源和輸出 alpha 通道值均為 1

讓我們看一些指定源和輸出 alpha 通道值的示例。第一個示例將輸出 alpha 通道值指定為與源 alpha 通道值相同,而第二個示例則指定一個與源 alpha 通道值無關的不同輸出 alpha 通道值。

css
oklab(from hsl(0 100% 50% / 0.8) l a b / alpha)
/* Computed output color: oklab(0.627966 0.22488 0.125859 / 0.8) */

oklab(from hsl(0 100% 50% / 0.8) l a b / 0.5)
/* Computed output color: oklab(0.627966 0.22488 0.125859 / 0.5) */

在下面的示例中,hsl() 源顏色再次被轉換為等效的 oklab() 顏色——oklab(0.627966 0.22488 0.125859)。然後將 calc() 計算應用於 LabA 值,最終得到輸出顏色 oklab(0.827966 0.14488 -0.0741406 / 0.9)

css
oklab(from hsl(0 100% 50%) calc(l + 0.2) calc(a - 0.08) calc(b - 0.2) / calc(alpha - 0.1))

備註:因為源顏色通道值被解析為 <number> 值,所以在使用它們進行計算時,你必須給它們加上數字,即使在通道通常接受 <percentage><angle> 或其他值型別的情況下也是如此。例如,將 <percentage> 新增到 <number> 是行不通的。

正式語法

<oklab()> = 
oklab( [ from <color> ]? [ <percentage> | <number> | none ] [ <percentage> | <number> | none ] [ <percentage> | <number> | none ] [ / [ <alpha-value> | none ] ]? )

<alpha-value> =
<number> |
<percentage>

示例

調整亮度

以下示例展示了改變 oklab() 函式的亮度、a 軸和 b 軸值的效果。

HTML

html
<div data-color="red-dark"></div>
<div data-color="red"></div>
<div data-color="red-light"></div>

<div data-color="green-dark"></div>
<div data-color="green"></div>
<div data-color="green-light"></div>

<div data-color="blue-dark"></div>
<div data-color="blue"></div>
<div data-color="blue-light"></div>

CSS

css
[data-color="red-dark"] {
  background-color: oklab(0.05 0.4 0.4);
}
[data-color="red"] {
  background-color: oklab(0.5 0.4 0.4);
}
[data-color="red-light"] {
  background-color: oklab(0.95 0.4 0.4);
}

[data-color="green-dark"] {
  background-color: oklab(5% -100% 0.4);
}
[data-color="green"] {
  background-color: oklab(50% -100% 0.4);
}
[data-color="green-light"] {
  background-color: oklab(95% -100% 0.4);
}

[data-color="blue-dark"] {
  background-color: oklab(0.05 -0.3 -0.4);
}
[data-color="blue"] {
  background-color: oklab(0.5 -0.3 -0.4);
}
[data-color="blue-light"] {
  background-color: oklab(0.95 -0.3 -0.4);
}

結果

調整不透明度

以下示例展示了改變 oklab() 函式的 A(alpha)值的效果。redred-alpha 元素與 #background-div 元素重疊,以演示不透明度的效果。將 red-alpha 元素的不透明度設為 0.4 使其看起來比 red 元素更透明。

HTML

html
<div id="background-div">
  <div data-color="red"></div>
  <div data-color="red-alpha"></div>
</div>

CSS

css
[data-color="red"] {
  background-color: oklab(0.628 0.225 0.126);
}
[data-color="red-alpha"] {
  background-color: oklab(0.628 0.225 0.126 / 0.4);
}

結果

調整顏色軸

此示例演示了將 oklab() 函式的 ab 值分別設定為 a 軸和 b 軸的端點和中點的效果。a 軸從綠色(-0.4)到紅色(0.4),b 軸從黃色(-0.4)到藍色(0.4)。

HTML

html
<div data-color="red-yellow"></div>
<div data-color="red-zero"></div>
<div data-color="red-blue"></div>

<div data-color="zero-yellow"></div>
<div data-color="zero-zero"></div>
<div data-color="zero-blue"></div>

<div data-color="green-yellow"></div>
<div data-color="green-zero"></div>
<div data-color="green-blue"></div>

CSS

我們使用 CSS 的 background-color 屬性,沿著 a 軸和 b 軸改變 oklab() 顏色函式的 ab 值,展示了每種情況下的最大值、中點值和最小值的影響。

css
/* a-axis max, variable b-axis */
[data-color="red-yellow"] {
  background-color: oklab(0.5 0.4 0.4);
}
[data-color="red-zero"] {
  background-color: oklab(0.5 0.4 0);
}
[data-color="red-blue"] {
  background-color: oklab(0.5 0.4 -0.4);
}

/* a-axis center, variable b-axis */
[data-color="zero-yellow"] {
  background-color: oklab(0.5 0 0.4);
}
[data-color="zero-zero"] {
  background-color: oklab(0.5 0 0);
}
[data-color="zero-blue"] {
  background-color: oklab(0.5 0 -0.4);
}

/* a-axis min, variable b-axis */
[data-color="green-yellow"] {
  background-color: oklab(0.5 -0.4 0.4);
}
[data-color="green-zero"] {
  background-color: oklab(0.5 -0.4 0);
}
[data-color="green-blue"] {
  background-color: oklab(0.5 -0.4 -0.4);
}

結果

左列位於 b 軸的黃色端(-0.4),右列位於藍色端(0.4)。頂行顯示了 a 軸紅色端(-0.4)的顏色,底行則是綠色端(0.4)。中間的行和列位於各自軸的中點,中間的單元格是灰色;它不含紅色、綠色、黃色或藍色,兩個軸的值都為 0

沿 a 軸和 b 軸的線性漸變

此示例包含線性漸變,以演示 oklab() 函式的值沿 a 軸(從紅到綠)和 b 軸(從黃到藍)的變化過程。在每個漸變影像中,一個軸保持不變,而另一個軸的值從低到高變化。

CSS

css
/* a-axis gradients */
[data-color="red-to-green-yellow"] {
  background-image: linear-gradient(to right, oklab(50% 0.4 0.4), oklab(50% -0.4 0.4));
}
[data-color="red-to-green-zero"] {
  background-image: linear-gradient(to right, oklab(50% 0.4 0), oklab(50% -0.4 0));
}
[data-color="red-to-green-blue"] {
  background-image: linear-gradient(to right, oklab(50% 0.4 -0.4), oklab(50% -0.4 -0.4));
}

/* b-axis gradients */
[data-color="yellow-to-blue-red"] {
  background-image: linear-gradient(to right, oklab(50% 0.4 0.4), oklab(50% 0.4 -0.4));
}
[data-color="yellow-to-blue-zero"] {
  background-image: linear-gradient(to right, oklab(50% 0 0.4), oklab(50% 0 -0.4));
}
[data-color="yellow-to-blue-green"] {
  background-image: linear-gradient(to right, oklab(50% -0.4 0.4),oklab(50% -0.4 -0.4));
}

結果

將 oklab() 用於相對顏色

此示例為三個 <div> 元素設定了不同的背景顏色。中間的元素使用了未經修改的 --base-color,而左右兩邊的元素則使用了該 --base-color 的提亮和變暗版本。

這些變體是使用相對顏色定義的——將 --base-color 自定義屬性傳遞給一個 oklab() 函式,然後透過一個 calc() 函式修改輸出顏色的亮度通道以達到預期效果。亮色變體的亮度通道增加了 0.15(15%),而暗色變體的亮度通道減少了 0.15(15%)。

CSS

css
:root {
  --base-color: orange;
}

#one {
  background-color: oklab(from var(--base-color) calc(l + 0.15) a b);
}

#two {
  background-color: var(--base-color);
}

#three {
  background-color: oklab(from var(--base-color) calc(l - 0.15) a b);
}

結果

輸出如下:

規範

規範
CSS 顏色模組第五版
# 相對 Oklab
CSS 顏色模組第四版
# ok-lab

瀏覽器相容性

另見