CSS 相對顏色語法

依據其他顏色的色頻和值建立新顏色。

Adam Argyle
Adam Argyle

Chrome 119 是 CSS 色彩等級 5 所提供的強大色彩功能。相對顏色語法可讓您在 CSS 中控制顏色的流暢路徑,讓作者和設計人員能夠進行以下操作:

之前,如要修改顏色的不透明度,您必須為顏色管道 (通常是 HSL) 建立自訂屬性,並將這些屬性組合成最終顏色和最終變化版本顏色。這表示要管理許多色彩,可能很快就會變得繁瑣。

:root {
  --brand-hue: 300deg;
  --brand-saturation: 75%;
  --brand-lightness: 50%;

  --brand-hsl:
    var(--brand-hue)
    var(--brand-saturation)
    var(--brand-lightness);

  --brand-color: hsl(var(--brand-hsl));

  /* all this work just so I can set the opacity to 50% in a variant */
  --brand-color-variant: hsl(var(--brand-hsl) / 50%);
}

之後,您可以使用所需的任何色域或語法來建立品牌顏色,並在程式碼較少的情況下建立半不透明度的變化版本。這樣也更容易閱讀樣式和系統的意圖。

:root {
  --brand-color: hsl(300deg 75% 50%);
  --brand-color-variant: hsl(from var(--brand-color) h s l / 50%);
}

這篇文章將協助您瞭解語法,並示範常見的色彩操控方式

如果您偏好使用影片,以下文章幾乎都涵蓋在這項 GUI 挑戰賽中。

語法總覽

相對色彩語法的目標在於允許從其他顏色衍生顏色。基本顏色稱為來源顏色,也就是新 from 關鍵字後方的顏色。瀏覽器會轉換並拆解這個原始顏色,並提供部分做為變數,以供新的顏色定義使用。

系統隨即會顯示語法 rgb(fromgreen r g b / alpha) 的圖表,其中有一個箭頭從綠色的頂部延伸至函式前方 RGB 的原點,這個箭頭會分割為 4 個箭頭,然後指向相關變數。4 個箭頭分別是紅色、綠色、藍色和 alpha。紅色和藍色的值為 0,綠色為 128,alpha 值為 100%。

上圖顯示原始顏色 green 已轉換成新顏色的色彩空間,並轉換為以 rgbalpha 變數表示的個別數字,然後直接用做新的 rgb() 顏色值。

雖然這張圖片顯示了細目的、程序和變數,但顏色也沒有改變。這些變數會重新放入顏色中,因此依然會呈現綠色。

from 關鍵字

要學習的語法的第一個部分是指定顏色的新增 from <color> 部分。指定值前,就必須先輸入此參數。以下是程式碼範例,其中新增的所有都是 from green,緊接在指定 rgb() 的值之前。

.syntax-introduction_same-colors {
  color: green;
  color: rgb(0 128 0);
  color: rgb(from green r g b);    /* result = rgb(0 128 0) */
}

from 關鍵字出現在函式標記法中的第一個參數時,會將顏色定義轉換為相對顏色!在 from 關鍵字之後,CSS 會預期能啟發下一種顏色的顏色

色彩轉換

簡單來說,則會將綠色轉換為 r g 和 b 管道,並用於新的顏色。

rgb(from green r g b)           /* r=0 g=128 b=0 */
rgb(from rgb(0 128 0) r g b);   /* r=0 g=128 b=0 */

自訂屬性中的顏色

閱讀《rgb from green》的內容清楚易懂。這就是為什麼自訂屬性和相對顏色語法非常相符,因為您可以消除 from 顏色的謎團。您通常也不需要瞭解自訂屬性顏色的顏色格式,因為您是根據自己選擇的格式建立新顏色。

rgb(from rgb(255 105 180) r g b) /* ????? */
rgb(from var(--hotpink) r g b)   /* clear */

在偏好的色域中作業

您可以選擇功能色彩標記法來選擇色域。

rgb(from hsl(120 100% 25%) r g b)     /*  r=0   g=128  b=0    */
hsl(from hsl(120 100% 25%) h s l)     /*  h=120 s=100% l=25%  */
hwb(from hsl(120 100% 25%) h w b)     /*  h=120 w=0%   b=50%  */
lch(from hsl(120 100% 25%) l c h)     /*  l=46  c=68   h=134  */

相對顏色語法包含該轉換步驟;from 之後的顏色會轉換為相對顏色開頭指定的顏色空間。輸入和輸出內容不需要比對,因為這相當精簡。

選擇色彩空間的功能也帶來許多助益,因為選擇色域時,比起偏好,選擇色域會更加著重在顏色變色類型。偏好設定會顯示在結果中,而非顏色格式或管道類型。在展示用途的章節中,這將會更加清楚,因為不同的色彩空間適用於不同任務。

混合、比對、省略及重複變數

這個語法有點奇怪,又令人興奮,因此變數不必依序傳回,並且可以重複。

rgb(from green g g g)    /* rgb(128 128 128) */
rgb(from green b r g)    /* rgb(0 0 128) */
rgb(from green 0 0 g)    /* rgb(0 0 128) */

以變數表示的不透明度

語法也會以名為 alpha 的變數提供不透明度。此為選用項目,位於函式顏色標記法的 / 後方。

rgb(from #00800080 r g b / alpha)             /* alpha=50% */
rgb(from rgba(0,128,0,.5) r g b / alpha)      /* alpha=50% */
rgb(from rgb(0 128 0 / 50%) r g b / alpha)    /* alpha=50% */

在變數上使用 calc() 或其他 CSS 函式

到目前為止,我們持續重複建立綠色的綠色燈號。瞭解語法、熟悉轉換作業和解構步驟。現在要修改變數並修改輸出內容,因此與輸入不同。

green                              /*  h=120 s=100% l=25%  */
hsl(from green calc(h * 2) s l)    /*  h=240 s=100% l=25%  */

現在是海軍了!色調加倍,將 120 色調變成 240,完全改變顏色。這樣做可以沿著色彩轉輪旋轉色調,幸好有 HSLHWBLCHOKLCH圓柱色空間,可實現簡單無比的做法。

透過圖表瞭解管道的值,讓您輕鬆計算數學數據,不需要猜測或記住規格,不妨試試這項「相對色彩語法通道值」工具。這項工具會根據您指定的語法顯示每個管道值,方便您確切掌握可以搭配哪些值一起播放。

檢查瀏覽器支援

@supports (color: rgb(from white r g b)) {
  /* safe to use relative color syntax */
}

應用實例與示範

以下例子和用途有許多替代語法,可以達到類似或相同的結果。這些變化來自顏色空間和相應的通路。

此外,許多範例都會使用 byto 的動詞顯示色彩調整。已變更顏色的 by 是一個相對顏色變更;變更會使用該變數的值,並根據變數目前的值進行調整。變更顏色的 to 是絕對顏色變更;這種變更不會使用變數的值,而是指定全新的值。

您可以在這個 Codepen 集合中找到所有示範內容。

調亮顏色

調亮顏色時,OKLCH、OKLABXYZsRGB 色域可以提供最準確的結果。

以特定金額調亮

以下 .lighten-by-25 範例使用 blue 顏色並將其轉換為 OKLCH,然後將 l (亮度) 管道乘以目前的值乘以 1.25,藉此將藍色變亮。這會將藍光朝白提升 25%。

.lighten-by-25 {
  background: oklch(from blue calc(l * 1.25) c h);
}

調亮特定值

以下範例 .lighten-to-75 不會使用 l 管道調暗 blue,而是將值完全取代為 75%

.lighten-to-75 {
  background: oklch(from blue 75% c h);
}

調暗顏色

相同的色域有助於調亮顏色,也很適合用來調暗顏色。

調暗幅度

以下 .darken-by-25 範例使用藍色顏色並將其轉換為 OKLCH,然後將 l (亮度) 管道值乘以 .75,將藍色調暗 25%。這會使藍色朝黑色上升 25%。

.darken-by-25 {
  background: oklch(from blue calc(l * .75) c h);
}

調暗到指定值

以下範例 .darken-to-25 不會使用 l 管道來調暗 blue,而是會將該值完全取代為 25%

.darken-to-25 {
  background: oklch(from blue 25% c h);
}

讓色彩飽和

以金額表示飽和

以下 .saturate-by-50 範例使用 hsl() 中的 s,依據相對 50% 增加 orchid 的震動。

.saturate-by-50 {
  background: hsl(from orchid h calc(s * 1.5) l);
}

達到特定金額

以下範例 .saturate-to-100 未使用 hsl()s 管道,而是指定所需的飽和度值。在這個例子中,飽和度會提高為 100%

.saturate-to-100 {
  background: hsl(from orchid h 100% l);
}

降低色彩飽和度

降低某個金額

以下範例 .desaturate-by-half 使用 shsl()indigo 的飽和度減半。

.desaturate-by-half {
  background: hsl(from indigo h calc(s / 2) l);
}

降低特定值

您不必因金額而低飽和度,而是可將值降到最低。以下 .desaturate-to-25 範例會根據 indigo 建立新顏色,但將飽和度設為 25%。

.desaturate-to-25 {
  background: hsl(from indigo h 25% l);
}

色域強化效果

這種效果與飽和度相似,但在某些方面有所不同。首先,這是 chroma 變更,而不是 saturation 變更,這是因為可以提升到高動態範圍的色彩空間不會使用飽和度。chroma 擁有高動態範圍的色彩空間,可讓作者強化色彩色彩,甚至比飽和度還高。

.increase-chroma {
  background: oklch(from orange l calc(c + .1) h);
}

調整顏色的不透明度

讓顏色的半透明變化版本是設計系統中最常見的色彩調整方式之一。如果錯過,請參閱本文開頭說明中的範例,其中也概要說明問題空間。

以金額調整不透明度

.decrease-opacity-by-25 {
  background: rgb(from lime r g b / calc(alpha / 2));
}

將不透明度調整為特定值

.decrease-opacity-to-25 {
  background: rgb(from lime r g b / 25%);
}

反轉色彩

色彩反轉是顏色程式庫中的常見色彩調整函式。其中一個方法是將顏色轉換為 RGB,然後將 1 減去每個管道的值。

.invert-each-rgb-channel {
  background: rgb(from yellow calc(255 - r) calc(255 - g) calc(255 - b));
}

相輔相成

如果您的目標是反轉顏色,而是想要補強色彩,那麼色調旋轉功能可能是需要的。挑選以角度做為色調的色域,然後使用 calc() 將色調旋轉所需數量。如要找出顏色的互補效果,請將 h 管道旋轉為一半。在此情況下,只要將 180 加減,即可達到結果。

.complementary-color {
  background: hsl(from blue calc(h + 180) s l);
}

對比色彩

如要達到無障礙的色彩對比度,請考慮使用 L&midast;(Lstar)。這會在 calc() 中使用 LCH 和 OKLCH 的 (概略) 一致亮度 (L) 管道。視您指定低、中或高對比度而定,L&midast;差異值約為約 40、約 50 或 60 次。

無論是 LCH 或 OKLCH 介面,都能透過這項技巧順利運作。

對比深色

.well-contrasting-darker-color 類別示範 L*,差異值為 60。由於原始顏色是深色 (低值亮度),因此系統會將 60% (.6) 加入亮度管道。這項技巧可用來在淺色背景上找出同樣鮮明的深色文字顏色。

.well-contrasting-darker-color {
  background: darkred;
  color: oklch(from darkred calc(l + .60) c h);
}

對比較淺的顏色

.well-contrasting-lighter-color 類別也示範 L*,差異幅度為 60%。由於原始顏色是淺色 (高值亮度),因此 .60 會從亮度管道減去。

.well-contrasting-lighter-color {
  background: lightpink;
  color: oklch(from lightpink calc(l - .60) c h);
}

調色盤

相對色彩語法很適合建立調色盤。由於可用的色彩空間數量龐大,這麼做會顯得格外實用且強大。以下範例全都使用 OKLCH,因為亮度管道十分可靠,而色調通道可在沒有副作用的情況下旋轉。最後一個範例展示了亮度和色調旋轉調整組合,讓結果更有趣!

開啟這些內容的範例原始碼,並嘗試變更 --base-color,瞭解這些調色盤的動態效果。很有趣!

如果您喜歡影片,我可以深入瞭解如何在 YouTube 上使用 OKLCH 在 CSS 中建構調色盤

單色調色盤

要建立單色調色盤,就是從相同的色調建立調色盤,但是亮度和暗度各有差異。中間顏色是調色盤的來源顏色,其中兩個較淺色和兩個較深的變化版本置於其中。

:root {
  --base-color: deeppink;

  --color-0: oklch(from var(--base-color) calc(l + .20) c h); /* lightest */
  --color-1: oklch(from var(--base-color) calc(l + .10) c h);
  --color-2: var(--base-color);
  --color-3: oklch(from var(--base-color) calc(l - .10) c h);
  --color-4: oklch(from var(--base-color) calc(l - .20) c h); /* darkest */
}
試試運用相對色彩語法和 OKLCH 製作的多種調色盤

Open Props 是免費的 CSS 變數程式庫,提供運用這項策略建構的調色盤,透過匯入功能即可輕鬆使用。而這些顏色全都是以可自訂的顏色為基礎,您只要為它上色,它就會形成調色盤!

類似調色盤

OKLCH 和 HSL 讓色調旋轉很容易,因此建立類似調色盤的並不容易。依自己喜歡的結果將色調旋轉、變更基本顏色,以及查看瀏覽器建構的新調色盤。

:root {
  --base-color: blue;

  --primary:   var(--base-color);
  --secondary: oklch(from var(--base-color) l c calc(h - 45));
  --tertiary:  oklch(from var(--base-color) l c calc(h + 45));
}

三角配色盤

與互補色類似,三角調色盤在使用基本顏色時會以相反的色調旋轉為主。輔助顏色位於顏色的對面 (例如透過色輪中間繪製的直線),三角調色盤就像是三角形線條,可以找出 2 個顏色完全從基本顏色旋轉。旋轉 120deg 即可完成這項設定。

以上只是簡化色彩理論的精簡版本,但如果您有興趣,可以先瞭解較複雜的三角配色盤。

:root {
  --base-color: yellow;
  --triad-1: oklch(from var(--base-color) l c calc(h - 120));
  --triad-2: oklch(from var(--base-color) l c calc(h + 120));
}

茶色調色盤

色調調色盤是在色輪上平均分割的四種顏色,建立一個沒有明確主要值的調色盤。你也可以想成是兩對互補色謹慎使用的話,這些資料會非常有意義。

這只是色彩理論略微簡化,但如果您有興趣,可直接開始探索較複雜的預測調色盤。

:root {
  --base-color: lime;

  --color-1: var(--base-color);
  --color-2: oklch(from var(--base-color) l c calc(h + 90));
  --color-3: oklch(from var(--base-color) l c calc(h + 180));
  --color-4: oklch(from var(--base-color) l c calc(h + 270));
}

單色 (略微旋轉)

許多色彩專家為這些誘惑做出調整。問題是,單色色尺可能相當無聊。解決方案是在亮度變更時,為每個新顏色加入小/明顯的色調旋轉。

以下範例將每個樣本的亮度降低 10%,同時將色調旋轉 10 度。因此,像漸層一樣流暢地混合的靛藍色調色盤。

:root {
  --base-color: deeppink;

  --color-1: var(--base-color);
  --color-2: oklch(from var(--base-color) calc(l - .10) c calc(h - 10));
  --color-3: oklch(from var(--base-color) calc(l - .20) c calc(h - 20));
  --color-4: oklch(from var(--base-color) calc(l - .30) c calc(h - 30));
  --color-5: oklch(from var(--base-color) calc(l - .40) c calc(h - 40));
}
試試這個以 OKLCH 和色調旋轉功能打造的排行榜

以下排行榜介面使用此色調旋轉策略。每個清單項目都會以名為 --i 的變數形式在文件中追蹤其索引。然後使用這個索引調整色度、亮度和色調。調整幅度只會增加 5% 或 5%,比上述範例的深粉色還差得多,因此需要注意這一點,才能知道這個排行榜處於任何色調狀態的原因。

請務必變更排行榜下方滑桿中的色調,然後查看相對色彩語法會建立美麗的色彩時刻。

li {
  --_bg: oklch(
    /* decrease lightness as list grows */
    calc(75% - (var(--i) * 5%))

    /* decrease chroma as list grows */
    calc(.2 - (var(--i) * .01))

    /* lightly rotate the hue as the list grows */
    calc(var(--hue) - (var(--i) + 5))
  );
}