Skip to content

Sass sass:color:調色、混色與取代 lighten 的做法

Sass 色彩模組 sass:color 的函式

sass:color 讓你從一個基準色算出整組色階:hover 的深一階、disabled 的淡一階、邊框的灰一階,全部由主色推導,設計改色時只要改一個變數。

scss
@use "sass:color";

四個調整函式

函式做什麼
color.scale()比例 往上下限靠近
color.adjust()加減 固定的量
color.change()直接 換掉 某個通道
color.mix()與另一個顏色 混合

scale:按比例縮放(首選)

scss
$brand: #2965f1;

.btn {
  background: $brand;

  &:hover {
    background: color.scale($brand, $lightness: -15%);
  }

  &:disabled {
    background: color.scale($brand, $saturation: -60%, $lightness: 30%);
  }
}

「亮度往下限靠近 15%」,不管原本多暗,結果永遠落在合法範圍內,不會撞到純黑。

adjust:加減固定值

scss
color.adjust($brand, $lightness: -15%);   // 亮度直接減 15 個百分點
color.adjust($brand, $hue: 30deg);        // 色相轉 30 度
color.adjust($brand, $alpha: -0.3);       // 透明度減 0.3

adjust 容易撞邊界

一個亮度只有 10% 的深色,adjust($c, $lightness: -15%) 會直接變成純黑,整組色階就糊在一起了。預設用 scale,需要精確的角度或透明度增減時才用 adjust

change:直接換掉

scss
color.change($brand, $alpha: 0.5);        // 保留色相彩度,只換透明度
color.change($brand, $lightness: 50%);    // 亮度直接設成 50%

半透明色最常用這個:

scss
.overlay {
  background: color.change(#000, $alpha: 0.6);
}

mix:混色

scss
color.mix(#2965f1, #fff, 20%);   // 20% 藍 + 80% 白 → 很淡的藍
color.mix(#2965f1, #000, 80%);   // 80% 藍 + 20% 黑 → 深一階

第三個參數是 第一個顏色的比例。做 tint 與 shade 色階很好用:

scss
@function tint($c, $amount) { @return color.mix($c, #fff, $amount); }
@function shade($c, $amount) { @return color.mix($c, #000, $amount); }

$brand-100: tint($brand, 15%);
$brand-900: shade($brand, 20%);

讀取通道

scss
color.channel($brand, "lightness", $space: hsl)   // 55%
color.channel($brand, "hue", $space: hsl)         // 222deg
color.channel($brand, "alpha")                    // 1

判斷背景深淺、決定文字要用黑還是白時很實用:

scss
@function contrast-text($bg) {
  @return if(color.channel($bg, "lightness", $space: hsl) > 60%, #1a1a1a, #fff);
}

舊的 lightness()、hue() 已被統一

以前每個通道一個函式,現在統一成 color.channel() 加通道名稱。

lighten 與 darken 的替代

舊寫法新寫法
lighten($c, 10%)color.scale($c, $lightness: 10%)
darken($c, 10%)color.scale($c, $lightness: -10%)
saturate($c, 20%)color.scale($c, $saturation: 20%)
transparentize($c, 0.3)color.adjust($c, $alpha: -0.3)
rgba($c, 0.5)color.change($c, $alpha: 0.5)

換過去之後顏色會不一樣

lighten() 是加法、scale() 是比例,兩者算出來的結果不同。遷移時要把每個顏色實際看過一遍,不能無腦替換。

Sass 調色 vs CSS 相對色彩

Sass color.*CSS 原生相對色彩
計算時機編譯期瀏覽器執行時
產出固定色碼保留函式寫法
能否吃 自訂屬性不行可以
相容性最好(產出是普通色碼)需要較新的瀏覽器

編譯期算得完的色階交給 Sass,需要跟著執行時主題變數走的交給 CSS。 分工見 搭配 CSS 自訂屬性,色彩表示法本身見 CSS 色彩

常見問題

scale 和 adjust 差在哪?

adjust 是加減固定的量,scale 是往上限或下限按比例靠近。對已經很亮或很暗的顏色,adjust 容易撞到邊界變成純白或純黑,scale 則永遠不會超出範圍,結果比較自然。

lighten 和 darken 還能用嗎?

還能編譯但已被棄用,會出現警告。替代寫法是 color.scale() 加上正負的 $lightness 參數。要注意兩者的計算方式不同,換過去之後顏色會有差異,需要重新確認。

怎麼取出一個顏色的色相或亮度?

color.channel() 並指定色彩空間,例如取 hsl 的 lightness 通道。舊版的 hue()lightness() 等個別函式已經被這個統一的寫法取代。

調色該在 Sass 做還是用 CSS 的相對色彩?

編譯期就能決定的色階用 Sass 算好,產出的是固定色碼,相容性最好。需要跟著執行時的主題變數走的,就交給 CSS 自訂屬性 搭配原生的相對色彩語法。

延伸閱讀