CSS color functions, gradients, color spaces title. What's new in CSS Colors Module Level 4 subtitle. A vibrant gradient behind artwork of a laptop and keyboard

CSS 顏色(Level 4)中的新函式、漸變和色相

閱讀時間 9 分鐘

越來越多的瀏覽器開始支援 CSS Colors Module Level 4 規範中定義的功能,該規範包含了在 CSS 中操作和顯示顏色的多種方法。讓我們一起來了解色彩空間、如何在 CSS 中定義顏色、CSS Colors Module Level 4 的新特性,以及你如何將這些顏色函式和特性運用到你的專案中。

理解色彩空間

要理解 CSS 中顏色的描述方式,快速瞭解色彩空間會有所幫助。色彩空間是基於定義的 顏色模型 對顏色進行分組的系統。色彩空間提供了一種清晰一致的描述顏色的方式,並且可以在不改變外觀的情況下將一種顏色轉換為另一種色彩空間。

在 CSS Colors Module Level 4 之前,CSS 中的顏色是在 RGB(紅、綠、藍)色彩空間和 色域(顏色的總範圍)中定義的。

A cube representing the RGB color space with red, green, and blue at the corners

隨著 HSL(色相、飽和度、亮度)支援的加入,你可以使用與 RGB 模型相同的模型來定義顏色,但改用色相、飽和度和亮度。我們將在下一節中更詳細地介紹 RGB 和 HSL。

在 CSS 中定義 RGB 顏色

要在 RGB 色彩空間中建立顏色,你需要以不同的方式混合紅、綠、藍這三種原色,以獲得所需的結果。你可以將其想象成一個立方體中的點座標,其中每個軸代表一種原色。

css
.red {
  color: rgb(255 0 0);
}
.green {
  color: rgb(0 255 0);
}
.blue {
  color: rgb(0 0 255);
}
/* yellow is a mix of red and green */
.yellow {
  color: rgb(255 255 0);
}
/* cyan is a mix of green and blue */
.cyan {
  color: rgb(0 255 255);
}

在 CSS 中定義 RGB 顏色時,你可以選擇使用顏色的關鍵字(如 redblue)、十六進位制值(#ff0000)或 rgb() 函式 來定義紅、綠、藍的值,如上面的示例所示。

根據 CSS Colors Module Level 4,你不再需要使用 rgba() 來定義帶 alpha 通道的 RGB 顏色,因為 rgb() 支援用斜槓(/)分隔的 alpha 值,如下所示。此示例演示瞭如何使用關鍵字、十六進位制值和 rgb() 函式來定義相同的顏色,其中還包括定義不透明度的示例。

css
.named-color {
  color: red;
}
.hex-color {
  color: #ff0000;
}
.rgb-color {
  color: rgb(255 0 0);
}
/* makes the color 50% transparent */
.rgba-semi-transparent {
  color: rgb(255 0 0 / 0.5);
}

使用 HSL 選擇色相

對 CSS 引入 HSL(CSS Colors Level 3) 的支援受到了許多開發者的歡迎,因為根據 色輪 選擇色相更加直觀。我們可以使用 conic-gradient() 函式和 hsl() 函式來建立一個色輪。製作這個漸變迴圈遍歷所有色相的技巧在下面的 色相插值 部分有描述。

css
#color-wheel {
  border-radius: 50%;
  background: conic-gradient(
    in hsl longer hue,
    hsl(0deg 100% 50%),
    hsl(360deg 100% 50%)
  );
}
/* For browsers that don't support hue interpolation methods */
@supports not (background: conic-gradient(in hsl longer hue)) {
  #color-wheel {
    background: conic-gradient(red, yellow, green, cyan, blue, magenta, red);
  }
}
html
<div id="color-wheel"></div>

如果我們結合這兩個程式碼片段,就可以建立一個迴圈遍歷 RGB 色彩空間中所有可用色相的色輪。

hsl() 函式的工作方式與 rgb() 函式類似,但接受色輪上的色相角度以及飽和度和亮度值。與 rgb() 一樣,你可以為 hsl() 新增 alpha 通道以實現透明度(或不透明度),這使得 hsla()rgba() 一樣成為遺留函式。

css
.red-hsl {
  color: hsl(0 100% 50%);
}
.green-hsl {
  color: hsl(120 100% 50%);
}
/* Make the color 50% opaque */
.green-hsl {
  color: hsl(120 100% 50% / 0.5);
}

HSL 函式的另一個便利之處在於,你可以透過改變飽和度和亮度來製作顏色的變體,而不必嘗試計算 RGB 值。例如,如果你為網站主題選擇了一種特定顏色,你可以修改該顏色的飽和度和亮度來建立一種仍然符合主題的二級顏色。這在下面進行了說明。

css
.button {
  color: hsl(200 100% 70%);
}
/* A darker version of the button color */
.button--secondary {
  color: hsl(200 100% 50%);
}
/* Lower saturation makes the button less vibrant */
.button--inactive {
  color: hsl(200 50% 70%);
}

CSS Colors Module Level 4 有哪些新特性?

此規範版本添加了許多使用不同顏色表示方式的新顏色函式,它們都允許你使用色相、亮度、飽和度等屬性來指定顏色。新的顏色函式使你能夠使用 RGB 色域之外的更鮮豔的顏色,因此在支援的顯示器上可用顏色範圍更廣。

支援更多色彩空間和色域

隨著對其他空間和色域的支援,你不再侷限於在 RGB 色彩空間中描述顏色;你現在可以使用 Display P3、CIELAB、Oklab 色彩空間。讓我們快速瞭解一下這些意味著什麼。

Display P3 使用 P3 色域,表示比 sRGB(標準 RGB)更寬的顏色範圍。它對於現代顯示器使用的更鮮豔的顏色非常有用。但是,你需要注意為不支援它的裝置的使用者提供回退方案。

CIELAB 是一個均勻色彩空間(UCS),它根據人眼對顏色的感知來定義顏色。該模型的主要目的是使顏色空間中兩點之間的相同顏色距離在觀眾看來同樣不同。

Oklab 是一個較新的色彩空間,它使用與 CIELAB 相同的模型結構,但透過“對視覺上相似的顏色資料集進行數值最佳化”而建立,因此其值旨在比 CIELAB 更準確。

CIELAB 和 Oklab 色彩空間不是用輪子、圓柱體或立方體來表示,而是可以表示為看起來像這樣的三維空間。

A three-dimensional representation of the CIELAB color space with points showing the location of some colors in the space.

顏色新函式式表示法

新的顏色函式有助於描述我們在上一節中看到的色彩空間中的值。讓我們看一下每個新函式及其工作方式。

lab() 函式式表示法使用亮度、紅/綠度(red/green-ness)和黃/藍度(yellow/blue-ness)沿色彩空間的“a”和“b”軸來描述 CIELAB 顏色。

css
.lab-red {
  color: lab(87.6 125 104);
}
.lab-green {
  color: lab(87.8 -79 81);
}

lch() 函式式表示法使用亮度、色度和色相來描述 CIELAB 顏色。色相是色輪上表示顏色的角度。

css
.lch-red {
  color: lch(54.3 107 40.9deg);
}
.lch-green {
  color: lch(87.8 113 134deg);
}

oklab() 函式式表示法使用亮度、紅/綠度(red/green-ness)和黃/藍度(yellow/blue-ness)沿 Oklab 色彩空間的“a”和“b”軸來描述 Oklab 顏色。

css
.oklab-red {
  color: oklab(0.63 0.22 0.13);
}
.oklab-green {
  color: oklab(0.87 -0.2 0.18);
}

oklch() 函式式表示法使用亮度、色度和色相來描述 Oklab 顏色。

css
.oklch-red {
  color: oklch(0.93 0.39 28deg);
}
.oklch-green {
  color: oklch(0.87 0.29 142deg);
}

除了新的色彩空間之外,還有一個用於 HWB 顏色的 hwb() 函式式表示法,它使用色相、白度和黑度來定義顏色。HWB 使用 RGB 色彩空間,與 HSL 類似,但考慮的是白度和黑度而不是飽和度和亮度。

css
.hwb-red {
  color: hwb(0deg 0% 0%);
}
.hwb-light-red {
  color: hwb(0deg 30% 0%);
}
.hwb-dark-red {
  color: hwb(0deg 0% 30%);
}
/* Cycle through the color wheel */
.hwb-green {
  color: hwb(120deg 0% 0%);
}
.hwb-blue {
  color: hwb(240deg 0% 0%);
}

最後,有一個 color() 函式式表示法,它允許你在預定義的色彩空間中指定顏色。

css
.green-display-p3 {
  color: color(display-p3 0 1 0);
}
.blue-rec2020 {
  color: color(rec2020 0 0 1);
}
.blue-srgb {
  color: color(srgb 0 0 1);
}

你還可以將 color() 函式式表示法與媒體查詢結合使用,以指定回退色彩空間。

css
.green-display-p3 {
  color: color(display-p3 0 1 0);
}
@media (color-gamut: srgb) {
  .green-display-p3 {
    color: color(srgb 0 1 0);
  }
}

顏色函式語法更改

rgb()hsl() 函式的語法已更改,旨在使其更易於使用。分隔值的逗號不再是必需的,你可以使用斜槓來為顏色指定 alpha 值。

css
/* old syntax */
rgb(255, 0, 0);
hsl(0, 100%, 50%);

/* new syntax */
rgb(255 0 0);
hsl(0 100% 50%);

/* new syntax with alpha channels */
rgb(255 0 0 / 0.5);
hsl(0 100% 50% / 0.5);

所有新函式都使用上述型別的語法,值之間沒有分隔逗號,並使用斜槓將 alpha 通道與顏色值分隔開。

色相插值

隨著新的色彩空間出現,其中一個好處是可以在不深入研究色彩科學的情況下建立漸變。插值是指在兩個已知值之間計算一個或多個值,因此如果你有一個從紅色到藍色的漸變,插值就是你計算紅色和藍色之間的顏色範圍的方式。在建立 linear-gradient() 或類似的 CSS 漸變時,你可以使用 in(表示插值)後跟漸變的色彩空間。

css
.hsl {
  background: linear-gradient(in hsl, blue, red);
}

比較不同色彩空間中的漸變

我們可以建立一個快速示例來比較不同色彩空間中的漸變。在下面的示例中,我們在標準 RGB 色彩空間中有一個從藍色到紅色的漸變,然後在不同的色彩空間中有相同的漸變。

css
.rgb {
  background: linear-gradient(to right, blue, red);
}

.hsl {
  background: linear-gradient(in hsl to right, blue, red);
}

.lch {
  background: linear-gradient(in lch to right, blue, red);
}

.lab {
  background: linear-gradient(in lab to right, blue, red);
}

.oklch {
  background: linear-gradient(in oklch to right, blue, red);
}

.oklab {
  background: linear-gradient(in oklab to right, blue, red);
}

這讓我們對不同色彩空間中的漸變外觀以及它們各自的插值工作方式有了很好的瞭解。

在漸變中使用色相插值模式

有一些 插值模式 可以控制在具有色相角度的色彩空間中,色相應該沿著色輪的哪個方向進行插值。

html
<div class="hsl in-function">
  <p>HSL</p>
</div>
<div class="hsl-named in-function">
  <p>HSL named</p>
</div>

<div class="hsl-longer in-function">
  <p>HSL (longer)</p>
</div>
<div class="hsl-named-longer in-function">
  <p>HSL named (longer)</p>
</div>

<div class="fallback">
  <p>Standard fallback</p>
</div>
css
/* From 39deg to 60deg, taking the shortest path around the color wheel */
.hsl {
  background: linear-gradient(
    to right in hsl,
    hsl(39deg 100% 50%),
    hsl(60deg 100% 50%)
  );
}
/* We can also use named colors */
.hsl-named {
  background: linear-gradient(to right in hsl, orange, yellow);
}

/* This gradient cycles back through 0deg around the color wheel */
.hsl-longer {
  background: linear-gradient(
    to right in hsl longer hue,
    hsl(39deg 100% 50%),
    hsl(60deg 100% 50%)
  );
}

/* The same effect can be achieved with named colors */
.hsl-named-longer {
  background: linear-gradient(to right in hsl longer hue, orange, yellow);
}

/* For browsers that don't support interpolation modes */
.fallback {
  background: linear-gradient(to right, blue, red);
}

瀏覽器支援

CSS Colors Module Level 4 中描述的大部分語法在最新版本的 Chrome 和 Safari 中都得到了支援,Firefox 113 開始支援顏色函式。上面示例中的色彩空間和插值模式的指定在 Chrome 和 Safari 中得到支援,但尚未在 Firefox 中支援。你可以檢視 MDN <color> 頁面 以獲取本文中介紹的其他功能的瀏覽器相容性資料。

總結

這裡快速回顧一下本文涵蓋的所有重點內容:

  • 對於 RGB 色彩空間,hwb() 函式式表示法允許你使用色相、白度和黑度來指定顏色。

  • 對於 CIELAB 色彩空間,你可以使用 lab()lch() 函式式表示法。

  • 對於 Oklab(類似於 CIELAB 色彩空間但資料更新),你可以使用 oklab()oklch() 函式式表示法。

  • 對於那些想深入研究不同色彩空間的人來說,color() 允許你使用 color(srgb) 來表示標準 RGB,並使用 color(display-p3) 來表示寬色域顯示器中使用的 Display P3。還有其他適合攝影師、影片專業人士和色彩科學家等專家的色彩空間。

    • color(rec2020):Rec2020 廣播行業標準色彩空間
    • color(prophoto-rgb):攝影師使用的 ProPhoto RGB 色彩空間
    • color(a98-rgb):Adobe RGB 色彩空間
    • color(xyz):CIE XYZ 色彩空間,其軸使用線性光強度以更好地預測顏色混合
    • color(srgb-linear):線性化 sRGB 色彩空間

下一步是什麼?

CSS Color Module Level 5 描述了一個 color-mix() 函式式表示法,它允許你使用指定的權重混合兩種顏色。此函式已在多個瀏覽器中得到支援,因此你可以立即開始嘗試,但值得關注 MDN color-mix() 頁面 以獲取瀏覽器相容性資料。在 color() 函式中,你將能夠使用透過 color(--my-color-space 0 0 0) 定義的自定義色彩空間,該自定義色彩空間使用 @color-profile 規則從外部檔案載入。

css
.plum-pink-mix {
  color: color-mix(in lch, plum, pink);
}

/* Custom color space */
@color-profile --example-color-space {
  src: url("https://example.org/my-color-profile.icc");
}
.header {
  background-color: color(--example-color-space 10% 20% 30%);
}

有用資源