新聞中心
在項(xiàng)目中經(jīng)常會(huì)碰到需要鄰近色的場(chǎng)景,比如將一個(gè)顏色變深(淺)一點(diǎn),下面是一個(gè)按鈕的選中態(tài)

如果出現(xiàn)一種顏色就定義一個(gè)變量,每次都要維護(hù)多個(gè)顏色變量太麻煩了。有沒(méi)有辦法只用一個(gè)顏色呢?在這里也就是,如何將一個(gè)顏色變淺一點(diǎn)?這樣做的好處是,如果需要更換主題色,只用修改一個(gè)變量就行了,如下:
下面盤(pán)點(diǎn)我用過(guò)的一些方法。
一、透明度
這應(yīng)該是最容易想到的方式。將一個(gè)元素透明度降低不就顏色變淺了嗎?
假設(shè) HTML是這樣的(下同)。
不過(guò)這種方式需要借助單獨(dú)一層標(biāo)簽,通常可以用偽元素生成,關(guān)鍵實(shí)現(xiàn)如下:
button::before{
content: '';
background: var(--primary-color);
opacity: 0.2
}效果還是非常不錯(cuò)的,下面是多種主題色的效果。
不過(guò)這種方式也有局限,比如偽元素不夠用怎么辦?還有絕對(duì)定位引起的層級(jí)問(wèn)題。
沒(méi)關(guān)系,還有其他方式,接著往下看。
二、多重背景
大家可能都知道,CSS3 背景是支持多重背景的,并且層級(jí)是越來(lái)越低的。
因此,我們可以在主題色上覆蓋一層半透明的白色,依然可以將原有顏色“減淡”。
由于這里是背景圖,所以需要用到漸變,而不是顏色。比如希望主題色減淡到自身的20%?,可以覆蓋80%透明度的白色,實(shí)現(xiàn)如下:
button{
background: linear-gradient(rgba(255,255,255,.8),rgba(255,255,255,.8)), /*半透明白色*/
linear-gradient(var(--primary-color), var(--primary-color));
}這樣就無(wú)需借助額外的標(biāo)簽或者偽元素了,效果如下:
不過(guò)這種方式也有一些缺陷,比如僅適合背景層,如果希望box-shadow、outline這些就不行,這些屬性沒(méi)法疊加多層背景。
三、動(dòng)畫(huà)
主要原理是動(dòng)畫(huà)播放次數(shù)也是支持小數(shù)的,比如設(shè)置一個(gè)從藍(lán)色到白色的動(dòng)畫(huà),播放次數(shù)為??0.8???,那么在播放到??80%??的地方就停下來(lái)了,這樣就得到了顏色減淡的效果,示意如下:
具體實(shí)現(xiàn)如下:
button{
animation: lighterBackgroundColor .001s 0.8 linear forwards;
/*播放次數(shù)為0.8*/
}
@keyframes lighterBackgroundColor {
from {
background-color: var(--primary-color)
}
to{
background-color: #fff
}
}效果也很棒。
相比前一種方式,就沒(méi)有背景的限制了,任意屬性都可以,但是每出現(xiàn)一個(gè)屬性就需要單獨(dú)一個(gè)動(dòng)畫(huà)(因?yàn)閯?dòng)畫(huà)變化的就是屬性本身),如果要加一個(gè)減淡后的outline-color,應(yīng)該要這么實(shí)現(xiàn)。
button{
animation: lighterBackgroundColor .001s 0.8 linear forwards,
lighterOutlineColor .001s 0.8 linear forwards; /*outline*/
/*播放次數(shù)為0.8*/
}
@keyframes lighterBackgroundColor {
from {
background-color: var(--primary-color)
}
to{
background-color: #fff
}
}
/*設(shè)置一個(gè)outline的動(dòng)畫(huà)*/
@keyframes lighterOutlineColor {
from {
outline-color: var(--primary-color)
}
to{
outline-color: #fff
}
}太繁瑣了,有沒(méi)有簡(jiǎn)單一點(diǎn)的方法呢?
四、自定義屬性動(dòng)畫(huà)
上面將屬性作為動(dòng)畫(huà)有點(diǎn)浪費(fèi),因?yàn)樽兓刀际且粯拥?,有沒(méi)有辦法復(fù)用呢?
當(dāng)然可以,將 CSS 變量作為動(dòng)畫(huà)對(duì)象,比如--lighterColor。
button{
animation: lighterColor .001s 0.8 linear forwards;
/*播放次數(shù)為0.8*/
}
@keyframes lighterColor {
from {
--lighterColor: var(--primary-color)
}
to{
--lighterColor: #fff
}
}但是,僅僅這樣是不夠的,動(dòng)畫(huà)并不認(rèn)識(shí)這樣的變量,根本不會(huì)有動(dòng)畫(huà)(就像display一樣)。
為了讓自定義變量也支持動(dòng)畫(huà),需要通過(guò)@property定義一下。
@property - CSS:層疊樣式表 | MDN (mozilla.org)[1]?。
@property --lighterColor {
syntax: '';
inherits: false;
initial-value: #fff;
} 相比前面的方式,但是適用性更佳,--lighterColor?已經(jīng)是一個(gè)獨(dú)立的變量了,可以用在任意屬性上,比如加個(gè)outline。
button{
background-color: var(--lighterColor);
outline: 4px solid var(--lighterColor);
}可以看到,outline也輕易地實(shí)現(xiàn)了顏色減淡。
缺點(diǎn)就是,兼容性欠佳,目前firefox還不支持
五、color-mix()
最后介紹一個(gè)最近正式支持(Chrome 110+)的顏色混合函數(shù):color-mix()[2]。
這個(gè)算是官方的解決方案了,如果這個(gè)普遍支持了,前面的方法都可以不用了,下面簡(jiǎn)單介紹一下。
color-mix(in lch, peru 40%, lightgoldenrod);
color-mix(in srgb, #34c9eb 20%, white);
前面的in lch?表示色彩空間,我們一般只用srgb就足夠了,后面的兩個(gè)顏色就需要混合的顏色了。
這里的百分比就是混合比例了,如果我們要實(shí)現(xiàn)減淡80%?的操作,可以將主題色的比例設(shè)置為20%,白色會(huì)自動(dòng)填充剩余比例,如下:
button{
--lighterColor: color-mix(in srgb, var(--primary-color) 20%, #fff);
background-color: var(--lighterColor);
outline: 4px solid var(--lighterColor);
}效果如下(Chrome 110+)。
目前還不適合使用,過(guò)兩年再說(shuō)吧。
下面是所有方案的效果對(duì)比,基本是一致的。
完整 demo 可以訪問(wèn)以下任意鏈接:
- CSS color lighter (juejin.cn)[3]
- CSS color lighter (codepen.io)[4]
- CSS color lighter (runjs.work)[5]
六、總結(jié)一下優(yōu)缺點(diǎn)
以上共介紹了5種不同的顏色混合實(shí)現(xiàn)方式,各有優(yōu)缺點(diǎn),下面分別從以下幾個(gè)方面比較一下
- 實(shí)現(xiàn)成本:實(shí)現(xiàn)思路的復(fù)雜度,是否容易想到。
- 適應(yīng)性:能否適應(yīng)各種場(chǎng)景。
- 代碼復(fù)用性:實(shí)現(xiàn)是否啰嗦,是否需要額外標(biāo)簽。
- 兼容性:能否大規(guī)模使用。
|
實(shí)現(xiàn)成本 |
適應(yīng)性 |
代碼復(fù)用性 |
兼容性 |
|
|
透明度 |
??(低) |
??(差) |
??(低) |
??????(好) |
|
多重背景 |
?? |
?? |
?? |
?????? |
|
動(dòng)畫(huà) |
??????(高) |
???? |
???? |
?????? |
|
自定義屬性動(dòng)畫(huà) |
???? |
??????(強(qiáng)) |
?????? |
???? |
|
color-mix |
?? |
?????? |
??????(高) |
??(差) |
總的來(lái)說(shuō),自定義屬性動(dòng)畫(huà)在各方面是比較推薦的,如果不考慮firefox的話基本可以放心使用了,其他方式也可以根據(jù)實(shí)際需求自行選擇,哪個(gè)方便用哪個(gè)。
參考資料
[1]@property - CSS:層疊樣式表 | MDN (mozilla.org): https://developer.mozilla.org/zh-CN/docs/Web/CSS/@property?。
[2]color-mix(): https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/color-mix?。
[3]CSS color lighter (juejin.cn): https://code.juejin.cn/pen/7206605166953365563?。
[4]CSS color lighter (codepen.io): https://codepen.io/xboxyan/pen/dyqRyVG?。
[5]CSS color lighter (runjs.work): https://runjs.work/projects/91dcf9cdd9f7447b?。
新聞標(biāo)題:CSS顏色混合的N種方式
轉(zhuǎn)載來(lái)源:http://fisionsoft.com.cn/article/dhidgcp.html


咨詢
建站咨詢
