前端基礎

-

CSS 超好用的混色功能 color-mix()

this.web

文章封面

你知道如何用 css 快速做出色輪嗎?或是你需要讓你的主色透明 10%?又或是你想要在黑暗模式時,將主色的混一點黑色降低飽和度?

在以往,以上功能的要自己手動去定義顏色才能做到,對沒有學過設計的工程師來說是一大難關,但現在,上面的問題都可以用 css 新的 color-mix() 來快速解決。

今天這篇文章就會帶你一步步認識並學會使用 CSS 的 color-mix,增加開發時的效率!

什麼是 color-mix()?

color-mix() 是在 CSS Color Module Level 5 中提出的 css 新函式,作用是將兩個顏色依照指定的比例混合,也能指定混合時所使用的色彩空間。

這在以前往往需要透過 Sass、Less 或者手動計算來達到。現在只要瀏覽器支援,就能在原生 CSS 中使用它。是我最愛用的函數之一,因為真的太方便了~

color-mix 語法介紹

color-mix() 的基本語法如下:

color-mix(in <color-space>, <color-stop> [, <color-stop>] )
  1. **<color-space>**:指定混色時所使用的色彩空間,例如 srgbdisplay-p3lablch 等。若省略,預設為 srgb
  2. **<color-stop>**:代表要混合的顏色,也可以選擇指定的比例。例如:
    • red 40%:混和 40% 的紅色
    • rgba(255, 0, 0, 0.5):不指定百分比時,預設為 50%
    • #00f 80%:使用 hex code 也沒問題
    • hsl(120, 100%, 50%) :hsl 也支援

當有兩個 color-stop 時,如果都沒有設定比例,則系統預設為 50% / 50%。

而如果你只設定第一個顏色的比例,第二個顏色比例會是剩餘的部分。

可直接指定兩個顏色各自的佔比,例如 red 70%, blue 30%。它們相加必須是 100%,否則會產生錯誤或未定義的行為。

範例 1:簡單兩色混合 (預設 srgb 空間)

.element {
  /* 混合 50% 的 red 與 50% 的 blue */
  background-color: color-mix(in srgb, red, blue);
}

範例 2:自定比例混色 (預設 srgb 空間)

.element {
  /* 混合 30% 的 red 與 70% 的 blue */
  background-color: color-mix(in srgb, red 30%, blue 70%);
}

範例 3:只指定一個顏色的比例 (預設 srgb 空間)

.element {
  /* 混合 80% red 與 20% blue */
  background-color: color-mix(in srgb, red 80%, blue);
}

色彩空間 (Color Spaces)

color-mix() 最常用的色彩空間是 srgb,但隨著顯示器技術的進步,更多廣色域的色彩空間(如 display-p3hsllch)也陸續被支援。使用不同的色彩空間會影響混色結果的精細度或視覺表現。

下圖是我根據常見的 srgb、display-p3、hsl、lch 色彩空間,並混合 50% 的藍色和 50% 的紅色來比對差異

.srgb {
  background: color-mix(in srgb, blue, red);
}
.p3 {
  background: color-mix(in display-p3, blue, red);
}
.hsl {
  background: color-mix(in hsl, blue, red);
}
.lch {
  background: color-mix(in lch, blue, red);
}
color-space

可以發現由於 sRGB 和 display-p3 更注重光線的混合,所以出來的結果是紫色,display-p3 稍微明亮一點。

而 hsl 和 lch 更注重人類對顏色的感知,而且除了顏色,亮度和飽和度也會影響在這兩個空間的算法,所以最後的結果偏粉色或紅色。

一般來說,使用 srgb 就很足夠了,支援度也稍微好一點。

color-mix 實戰範例

範例 1:利用 color-mix() 製作更好看的漸層

一般我們直接使用 linear-gradient 製作漸層時,常常會因為中間的顏色偏灰而讓整體的效果變得不好看。

例如我們直接使用紅和藍來做漸層,就會發現中間的顏色有點髒髒的,不是那麼好看。

.my-gradient {
  --start-color: red;
  --end-color: blue;

  background: linear-gradient(
    to right,
    var(--start-color),
    var(--end-color)
  );
}
normal-linear

此時就可以用 color-mix 來幫我們和出好看的中間色,像這邊我使用 lch 這個色彩空間來幫我混和,因為這個色彩空間會保持相同的顏色明亮度。

.my-gradient {
  --start-color: red;
  --end-color: blue;

  /* 先計算中間顏色 = 50% 紅 + 50% 藍 */
  --middle-color: color-mix(in srgb, var(--start-color) 50%, var(--end-color) 50%);

  background: linear-gradient(
    to right,
    var(--start-color),
    var(--middle-color),
    var(--end-color)
  );

成果好看很多!

lch-linear

範例 2:動態主題切換(淺色 / 深色)

很多現代網站都支援切換淺色和深色模式,如果想在深色模式下的,保持相同品牌的主色風格,但又不希望主色太亮眼,就能透過 color-mix() 設置主色與背景色的混合比例,讓主色自動過渡到一個合宜的顏色。

:root {
  --brand-color: #6200ee; /* 主品牌色 */
  --dark-bg-color: #121212;
}

@media (prefers-color-scheme: dark) {
  :root {
    /* 在暗色模式中,品牌色和背景色進行一定比例混合,讓整體感更柔和 */
    --brand-color: color-mix(in srgb, #6200ee 70%, var(--dark-bg-color) 30%);
  }
}

.theme-button {
  background-color: var(--brand-color);
  color: #fff;
  padding: 10px;
  border: none;
  border-radius: 4px;
}
dark-mode

範例 3 : 製作色輪

透過 color-mix 我們也可以非常輕鬆的製作和主色相關的色輪,這邊我是直接混合白色做到這樣的效果

.wheel .red:nth-child(1) {
  background-color: color-mix(in srgb, red 100%, white 0%);
}
.wheel .red:nth-child(2) {
  background-color: color-mix(in srgb, red 90%, white 10%);
}
.wheel .red:nth-child(3) {
  background-color: color-mix(in srgb, red 80%, white 20%);
}
.wheel .red:nth-child(4) {
  background-color: color-mix(in srgb, red 70%, white 30%);
}

...
wheel

目前瀏覽器支援 color-mix 的狀況

既然是新屬性,那勢必要注意瀏覽器的支援度,在寫這篇文章的時候支援度是 91%,算可以用了,如果擔心的話,在 Side Project 和內部專案使用是沒有太大的問題。

支援度

你可以在 Can I use 網站上檢查最新支援狀況。

相容性與回退 (Fallback)

如果你擔心支援度的問題,其實只要搭配 @supports 就能很好的解決這個問題,它能夠讓我們做條件判斷,再不支援的瀏覽器上退回預設使用用的顏色,這樣就能確保在不支援 color-mix() 時,至少有一個預設顏色可以顯示。

.element {
  /* 預設使用回退顏色 */
  background-color: #ff6600; 
}

@supports (background-color: color-mix(in srgb, red, blue)) {
  .element {
    /* 如果瀏覽器支援 color-mix,就使用混色 */
    background-color: color-mix(in srgb, red 30%, blue 70%);
  }
}

結語

color-mix() 為 CSS 帶來了更彈性且強大的混色能力,過去許多需要透過預處理器或圖像軟體才能完成的工作,現在只要瀏覽器支援,就能直接在 CSS 中完成。真的是工程師的一大福音。

但由於它相對新穎,實際專案運用時還是需要考慮到瀏覽器支援度的問題。

參考連結:

你可能會感興趣的文章 👇