告別繁瑣的顏色變數管理,讓你的網頁配色更聰明!

作為網頁設計師或前端開發者,你是否也受夠了這種情況:每次在設計一個新網站時,總需要定義多組色彩,像是在網頁設定一個文字連結,並希望文字連結在按下前、按下後以及滑鼠 Hover 時都能有一些顏色的變化,方便用戶知道自己有沒有按過這個連結。這種情況你就需要為每個文字連結的狀態設定不同顏色 RGB 碼,一旦你要修改某個文字連結的顏色,就需要連同相關的狀態色一起調整。如果你的網頁有提供多種主題,如:深色、淺色的閱讀模式或是針對色盲的用戶提供專用的配色,網頁上需要設定的色彩組合就直接翻上好幾翻。

這種傳統的設定方式不僅效率低下,在需要修改的時候還可能發生東補西漏的問題,雖然有些人嘗試將 RGB 色碼拆分為多個獨立的 CSS 變數,增加一些維護的方便,但當你需要調整顏色的時候,還是一樣得手動更新所有相關變數,耗時又容易出錯。

什麼是 Relative Colors 相對色彩?

如果你也被上面的問題所困擾,有個好消息,CSS 的新功能 Relative Colors 相對顏色將會有機會解決這個問題!

Relative Colors 相對顏色是 CSS Color Module Level 5 引入的一項新功能,它允許開發者基於現有顏色 (下面以原色稱呼) 來定義新的顏色組,從而建立任意多組色彩組合以對應網頁元件的不同狀態。讓你用更少的變數管理更豐富的網頁配色,也讓 CSS 更簡潔、更易維護。

傳統的標色方式如下

color: rgb(r, g, b);

相對顏色使用 from 關鍵字,語法結構如下:

color: rgb(from 原色 r g b / alpha);

與傳統的標色方式相比多了「from」及「原色」兩組設定。

  • from 是相對色彩的關鍵字,意思是將這組色彩的設定為相對色彩,並指定一組原色。
  • 原色:你可以在原色上任意指定一個顏色,並透過調整該顏色後面的色彩通道,從而得到任意多組的色彩組合。

解決傳統配色需要設定多組色彩變數的管理痛點

在了解相對色彩的用法後,下面我們以一個文字連結的設定說明傳統的標色方式與相對色彩在使用上的差異。

在傳統的做法中,要讓一個文字連結在不同狀態下有不同的顏色時,需要為每個狀態設置不同的色碼,也就是一個「固定的數值」,設定完成後你基本上無法改變它,如果要在 Hover 的狀態下顯示另一個顏色,你就需要在 Hover 指定另一個色碼,具體的方式如下:

.text-link:link{
  color: red;
}
.text-link:visited{
  color: green;
}
.text-link:hover{
  color: blue;
}
.text-link:active{
  color: pink;
}

但在相對色彩的做法下,我們可以用一個指定的原色,並透過對原色參數的調整,從而獲得新的色彩,當我們需要改變這組色彩配色時,也只要改變原色即可,其它如 :link、:visited...都會隨著原色而自動改變,這就是為什麼它會被稱為相對色彩的原因,使用範例方式如下:

:root {
  --text-color: rgb(255, 0, 0);
}

.text-link:link {
  color: var(--text-color);
}

.text-link: visited{
  color: rgb(from var(--text-color) calc(r - 50) calc(g + 100) b);
}

.text-link:hover {
  color: rgb(from var(--text-color) calc(r - 100) calc(g + 200) b);
}

.text-link:active {
  color: rgb(from var(--text-color) calc(r - 150) calc(g + 250) b);
}

也就是說,我們可以透過一組原色就配出多出任意多組對應色,以對應元件的不同狀態 (如文字連結元件的 :link、:visited、:hover、:active)。在極端的情況下,我們甚至可以只透過一個原色,就自行條配出整個網站所需的色彩組合,雖然這個例子在實務上不太合適,但卻可以很好的說明相對色彩在應用上的優勢。

Relative Colors 相對色彩與傳統的標色方式,在使用上有下面幾個特點:

  1. 基於原色做二次調色
  2. 顏色通道:可以直接訪問顏色的各個通道(rgb、hsl... 等)
  3. 數學運算:可以透過 calc() 對通道的數值進行加、減、乘、除的計算

什麼是 HSL 色彩模型?

在了解 Relative Colors 的使用方式後,我們還需要先解釋一下什麼是 HSL。與傳統的 RGB 紅、綠、藍的色彩模型相比,HSL 指的是色相 (H)、飽和度(S)、亮度(L)。

  • 色相 (Hue):代表顏色在色輪上的位置(0-360 度),由紅、橙、黃、綠、藍、靛、紫逐項漸變。
  • 飽和度 (Saturation):表示顏色的鮮豔程度(0% 為灰色,100% 為最鮮豔)。
  • 亮度 (Lightness):控制顏色的明暗(0% 為黑色,100% 為白色,純色為 50%)。

與 RGB 相比,HSL 的優勢在哪?

RGB 顏色模型基於紅、綠、藍三色的混合。雖然在技術上能夠表示所有顏色,但它與人類感知顏色的方式不太吻合。例如,要讓一個 rgb(255, 0, 0)(純紅)變亮,你可能需要增加綠色和藍色的值,但這會讓顏色偏離純紅,變成粉色或白色。如果只是想讓它單純變淺而不改變「紅」的本質,在 RGB 中操作會非常困難且不直觀。

反之,HSL 則更便於想像,我們可以先在網頁元件上指定一個色相,如紅色,接這透過飽和度的設定,調整無數組由新鮮到混濁的紅,也可以透過亮度的調整,將紅色往粉紅及暗紅兩端調整。也就是說,你只要有一點色相、飽和度及亮度的基本認識,可以很輕易的在腦中想像這組紅色的變化,並設定多組相似的鄰近色,用以對應元素的不同狀態,下面是一個簡單的例子及說明:

:root {
  --btn-color: hsl(0, 100%, 50%);
}

.btn {
  color: var(--btn-color);
}

.btn:hover {
  /* 透過 clac() 改變數值,從而得到更深的紅色 */
  color: hsl(from var(--btn-color) h s calc(l - 25));
}

現階段在 HSL 下使用 calc() 會有一些問題需要注意

另外我在 HSL 色彩模式下使用 calc() 等數學函數的時候,會發生無法作用的情況,在 RGB 模式反而就正常了。查詢網路的相關討論後,目前歸納出比較可能的原因會是:

  • CSS 規範的解析行為與瀏覽器實現的細微差異,或是單純的瀏覽器還不相容該用法。
  • RGB 是純粹的數字加總,如 calc(255 - 100),而 hsl 涉及到單位,如 calc(100% - 50%),可能現階段在瀏覽器下實現單位的轉換還有問題。

因此,現階段最保險的方式是直接給一個固定的數值,而非透過數學函數去進行計算。

color: hsl(from var(--btn-color) h s 25%);

如果你需要使用 calc() 則可以配合使用無單位的數值:

color: hsl(from var(--btn-color) h s calc(l - 20));

結尾

儘管 HSL 模式下 calc() 仍有兼容性的問題,這也正是一項新技術發展的必經階段。身為設計師的你,也許可以開始從小型的專案導入 Relative Colors,搭配 CSS 變數層級管理,建立更有彈性、精簡的色彩架構。我相信假以時日,隨著技術的成熟,就如同 flexbox 淘汰 float 的排版方式,能讓設計師將更多精力投入創意的發想,建構更靈活有彈性的網頁。

由於本篇文章比較長,我們的簡單的回顧一下文章的重點:

  • 傳統的標色方式採用固定色碼,會導致變數過多、管理困難的毛病。
  • 相對色彩是為了解決固定色碼所帶來的不便,讓你可以透過一組原色,自行配出任意多組色彩,用以對應網頁元素的不同狀態。
  • 相對色彩可以使用 RGB、HSL 等方式來標色,但由於 HSL 使用上更直觀的關係,更適合拿來與相對色彩交互搭配。
  • 現階段使用相對色彩+HSL+calc() 會有一些相容性的問題要注意。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

返回頂端