妙用 CSS 動畫來實(shí)現(xiàn)顏色加深、減淡等混合操作

在上一篇 CSS 如何根據(jù)背景色自動切換黑白文字?中,講述了文本自適應(yīng)背景色的一些小技巧,不過還存在一定局限性,比如:如果是背景是漸變色該怎么辦?

很容易想到的思路是將兩個漸變色取過渡中間色,然后再通過前面的方式轉(zhuǎn)換就行了。

那么問題來了,有沒有辦法通過 CSS 實(shí)現(xiàn)中間顏色的獲取呢?下面來一起探討這個問題,聊一聊關(guān)于顏色合成的相關(guān)技巧。
一、你可能不知道 CSS 動畫小技巧
想必大家都用過 CSS 動畫,比如
這樣就得到了一個顏色從yellow到deeppink的動畫。

這個沒什么好說的。
默認(rèn)情況下,動畫會播放 1 次后結(jié)束,然后設(shè)置了forwards,會保留在最后一幀狀態(tài)。
那么,如果動畫只播放一半,是不是就正好處于兩者顏色的中間?其實(shí),播放次數(shù)也可以是小數(shù)的,比如可以將播放次數(shù)設(shè)置為0.5次,就像這樣。
效果如下:

由于只播放了一半,所以到中間的橙色就停止了下來。
值得一提的是,通過這種方式得到的顏色,也是可以用 JS 去獲取的。

那么,利用這個特性,可以實(shí)現(xiàn)顏色的各種合成效果。
二、漸變背景下的文本自適應(yīng)
回到前面的問題,如果是漸變背景,該如何實(shí)現(xiàn)自動切換黑白文字呢?
假設(shè)漸變的兩種顏色分別是--c1和--c2。
那么根據(jù)上一節(jié)的方法,可以將動畫改造成這樣。
我們這里只是需要獲取一下顏色,并不需要動畫,所以可以將動畫時長設(shè)置為很小的一個數(shù),比如0.001s。
這樣文字顏色就自動變成了漸變顏色的中間值,如下:

然后再應(yīng)用濾鏡,將文字轉(zhuǎn)換成黑色或者白色。
效果如下:

也能完美適配任意漸變色。

完整代碼可以查看以下任意鏈接
- CSS auto-gradient-color (juejin.cn)[1]
- CSS auto-gradient-color (codepen.io)[2]
- CSS auto-gradient-color (runjs.work)[3]
三、顏色的加深和減淡
再來看一個更加實(shí)用的例子,顏色的加深和減淡。通常用于主題色的生成,比如給定一個主題色,生成一系列和它相匹配的鄰近色。下面是顏色逐漸減淡,最終變?yōu)榘咨纳A圖。

根據(jù)上面的原理,可以很輕易的實(shí)現(xiàn)這樣一個效果。
假設(shè) HTML 是這樣的,每個方塊給一個不同的 CSS 變量--l。
然后創(chuàng)建一個從主題色到白色的動畫,根據(jù)這個變量,讓動畫執(zhí)行不同的次數(shù)。
這樣就可以生成同種顏色,不同深淺度的主題色了
有同學(xué)可能會說像 sass、less這些不也能實(shí)現(xiàn)嗎?其實(shí)不然,這些都是預(yù)處理器,生成以后就不能再變了,而這種方式是實(shí)時繪制的,可以實(shí)時修改,如下

完整代碼可以查看以下任意鏈接:
- CSS lighten (juejin.cn)[4]
- CSS lighten (codepen.io)[5]
- CSS lighten (runjs.work)[6]
如果將這種技巧用到實(shí)際項(xiàng)目中也是非常完美,下面是不同主題色下的預(yù)覽效果。

選中背景色就是減淡80%后的顏色。
原理是完全相同的,這里就不詳細(xì)介紹了,完整代碼可以查看以下任意鏈接。
- CSS color-mix (juejin.cn)[7]
- CSS color-mix (codepen.io)[8]
- CSS color-mix (runjs.work)[9]
除此之外,根據(jù)需求,還可以通過顏色透明度的變化來生成特定透明度的主題色。
四、未來最期待的幾個顏色處理函數(shù)
官方也看到了這種需求,因此在 CSS Color Module Level 5[10]中起草了幾個關(guān)于顏色合成的函數(shù),這里簡單介紹一下。
首先是顏色混合color-mix,將兩種顏色按照一定的比例進(jìn)行融合。
這表示white和blue按照各自 50% 進(jìn)行混合,最終會得到紫色rgb(50% 50% 100%)。
如果要控制混合比例,可以這樣。
還有一個叫做相對顏色relative color ,其實(shí)是對原有的顏色函數(shù)進(jìn)行了補(bǔ)充,根據(jù)我的理解,可以將這個特性想象成 JS 中的解構(gòu)賦值。
例如這個表示將顏色--accent分解成h、s、l三個變量,然后對其中的l,也就是亮度減少20%,也就達(dá)到了顏色變暗的目的。
多么令人興奮的特性!目前這兩個特性僅在 safari 15+試驗(yàn)性功能開啟支持(??終于不拖后腿了)。

五、總結(jié)一下
以上就是本文全部內(nèi)容了,主要是利用 CSS 動畫的過渡特性,間接達(dá)到了顏色合成的目的,下面是一些要點(diǎn):
- CSS 動畫的次數(shù)也能設(shè)置成小數(shù),比如 0.5 表示動畫只運(yùn)行到一半。
- 兩個顏色的中間色就是顏色動畫運(yùn)行到一半的狀態(tài)。
- 顏色減淡可以看成是主題色到白色的動畫,加深則是黑色。
- 官方已經(jīng)正在起草 CSS 顏色合成相關(guān)函數(shù),目前僅 Safari 試驗(yàn)性支持。
你學(xué)會了嗎?總的來說,在color-mix到來之前,這樣一個小技巧還算是不錯的解決方案。
參考資料
[1]CSS auto-gradient-color (juejin.cn): ??https://code.juejin.cn/pen/7182116774291177509。
[2]CSS auto-gradient-color (codepen.io): ??https://codepen.io/xboxyan/pen/wvxMjyg。
[3]CSS auto-gradient-color (runjs.work): ??https://runjs.work/projects/665883ec8f554759。
[4]CSS lighten (juejin.cn): ??https://code.juejin.cn/pen/7182130832608346146。
[5]CSS lighten (codepen.io): ??https://codepen.io/xboxyan/pen/PoBZapJ。
[6]CSS lighten (runjs.work): ??https://runjs.work/projects/cff8abbeb12e4950。
[7]CSS color-mix (juejin.cn): ??https://code.juejin.cn/pen/7182134966540009529。
[8]CSS color-mix (codepen.io): ??https://codepen.io/xboxyan/pen/jOpWKxX。
[9]CSS color-mix (runjs.work): ??https://runjs.work/projects/3d34d06657d0411c。
[10]CSS Color Module Level 5: ??https://www.w3.org/TR/css-color-5。





























