CSS 顏色混合的五種實現(xiàn)方式

如果出現(xiàn)一種顏色就定義一個變量,每次都要維護多個顏色變量太麻煩了。有沒有辦法只用一個顏色呢?在這里也就是,如何將一個顏色變淺一點?這樣做的好處是,如果需要更換主題色,只用修改一個變量就行了。
在項目中經(jīng)常會碰到需要鄰近色的場景,比如將一個顏色變深(淺)一點,下面是一個按鈕的選中態(tài)
如果出現(xiàn)一種顏色就定義一個變量,每次都要維護多個顏色變量太麻煩了。有沒有辦法只用一個顏色呢?在這里也就是,如何將一個顏色變淺一點?這樣做的好處是,如果需要更換主題色,只用修改一個變量就行了,如下:
下面盤點我用過的一些方法。
一、透明度
這應(yīng)該是最容易想到的方式。將一個元素透明度降低不就顏色變淺了嗎?
假設(shè) HTML是這樣的(下同)。
<button style="--primary-color: #3981E6">#3981E6</button>
不過這種方式需要借助單獨一層標(biāo)簽,通??梢杂脗卧厣?,關(guān)鍵實現(xiàn)如下:
button::before{ content: ''; background: var(--primary-color); opacity: 0.2 }
效果還是非常不錯的,下面是多種主題色的效果。
不過這種方式也有局限,比如偽元素不夠用怎么辦?還有絕對定位引起的層級問題。
沒關(guān)系,還有其他方式,接著往下看。
二、多重背景
大家可能都知道,CSS3 背景是支持多重背景的,并且層級是越來越低的。
因此,我們可以在主題色上覆蓋一層半透明的白色,依然可以將原有顏色“減淡”。
由于這里是背景圖,所以需要用到漸變,而不是顏色。比如希望主題色減淡到自身的20%?,可以覆蓋80%透明度的白色,實現(xiàn)如下:
button{ background: linear-gradient(rgba(255,255,255,.8),rgba(255,255,255,.8)), /*半透明白色*/ linear-gradient(var(--primary-color), var(--primary-color)); }
這樣就無需借助額外的標(biāo)簽或者偽元素了,效果如下:
不過這種方式也有一些缺陷,比如僅適合背景層,如果希望box-shadow、outline這些就不行,這些屬性沒法疊加多層背景。
三、動畫
主要原理是動畫播放次數(shù)也是支持小數(shù)的,比如設(shè)置一個從藍色到白色的動畫,播放次數(shù)為??0.8?
??,那么在播放到??80%?
?的地方就停下來了,這樣就得到了顏色減淡的效果,示意如下:
具體實現(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 } }
效果也很棒。
相比前一種方式,就沒有背景的限制了,任意屬性都可以,但是每出現(xiàn)一個屬性就需要單獨一個動畫(因為動畫變化的就是屬性本身),如果要加一個減淡后的outline-color,應(yīng)該要這么實現(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è)置一個outline的動畫*/ @keyframes lighterOutlineColor { from { outline-color: var(--primary-color) } to{ outline-color: #fff } }
太繁瑣了,有沒有簡單一點的方法呢?
四、自定義屬性動畫
上面將屬性作為動畫有點浪費,因為變化值都是一樣的,有沒有辦法復(fù)用呢?
當(dāng)然可以,將 CSS 變量作為動畫對象,比如--lighterColor。
button{ animation: lighterColor .001s 0.8 linear forwards; /*播放次數(shù)為0.8*/ } @keyframes lighterColor { from { --lighterColor: var(--primary-color) } to{ --lighterColor: #fff } }
但是,僅僅這樣是不夠的,動畫并不認(rèn)識這樣的變量,根本不會有動畫(就像display一樣)。
為了讓自定義變量也支持動畫,需要通過@property定義一下。
@property - CSS:層疊樣式表 | MDN (mozilla.org)[1]?。
@property --lighterColor { syntax: '<color>'; inherits: false; initial-value: #fff; }
相比前面的方式,但是適用性更佳,--lighterColor?已經(jīng)是一個獨立的變量了,可以用在任意屬性上,比如加個outline。
button{ background-color: var(--lighterColor); outline: 4px solid var(--lighterColor); }
可以看到,outline也輕易地實現(xiàn)了顏色減淡。
缺點就是,兼容性欠佳,目前firefox還不支持
五、color-mix()
最后介紹一個最近正式支持(Chrome 110+)的顏色混合函數(shù):color-mix()[2]。
這個算是官方的解決方案了,如果這個普遍支持了,前面的方法都可以不用了,下面簡單介紹一下。
color-mix(in lch, peru 40%, lightgoldenrod); color-mix(in srgb, #34c9eb 20%, white);
前面的in lch?表示色彩空間,我們一般只用srgb就足夠了,后面的兩個顏色就需要混合的顏色了。
這里的百分比就是混合比例了,如果我們要實現(xiàn)減淡80%?的操作,可以將主題色的比例設(shè)置為20%,白色會自動填充剩余比例,如下:
button{ --lighterColor: color-mix(in srgb, var(--primary-color) 20%, #fff); background-color: var(--lighterColor); outline: 4px solid var(--lighterColor); }
效果如下(Chrome 110+)。
目前還不適合使用,過兩年再說吧。
下面是所有方案的效果對比,基本是一致的。
完整 demo 可以訪問以下任意鏈接:
- CSS color lighter (juejin.cn)[3]
- CSS color lighter (codepen.io)[4]
- CSS color lighter (runjs.work)[5]
六、總結(jié)一下優(yōu)缺點
以上共介紹了5種不同的顏色混合實現(xiàn)方式,各有優(yōu)缺點,下面分別從以下幾個方面比較一下
- 實現(xiàn)成本:實現(xiàn)思路的復(fù)雜度,是否容易想到。
- 適應(yīng)性:能否適應(yīng)各種場景。
- 代碼復(fù)用性:實現(xiàn)是否啰嗦,是否需要額外標(biāo)簽。
- 兼容性:能否大規(guī)模使用。
實現(xiàn)成本 | 適應(yīng)性 | 代碼復(fù)用性 | 兼容性 | |
透明度 | ??(低) | ??(差) | ??(低) | ??????(好) |
多重背景 | ?? | ?? | ?? | ?????? |
動畫 | ??????(高) | ???? | ???? | ?????? |
自定義屬性動畫 | ???? | ??????(強) | ?????? | ???? |
color-mix | ?? | ?????? | ??????(高) | ??(差) |
總的來說,自定義屬性動畫在各方面是比較推薦的,如果不考慮firefox的話基本可以放心使用了,其他方式也可以根據(jù)實際需求自行選擇,哪個方便用哪個。
參考資料
[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?。
到此這篇關(guān)于CSS 顏色混合的五種實現(xiàn)方式的文章就介紹到這了,更多相關(guān)CSS 顏色混合內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持腳本之家!
相關(guān)文章
- CSS Grid 是一種二維布局系統(tǒng),可以同時控制行和列,相比 Flex(一維布局),更適合用在整體頁面布局或復(fù)雜模塊結(jié)構(gòu)中,這篇文章主要介紹了前端CSS Grid 布局詳解,需要的朋2025-04-16
CSS Padding 和 Margin 區(qū)別全解析
CSS 中的 padding 和 margin 是兩個非?;A(chǔ)且重要的屬性,它們用于控制元素周圍的空白區(qū)域,本文將詳細介紹 padding 和 margin 的概念、區(qū)別以及如何在實際項目中使用它們2025-04-07- will-change 是一個 CSS 屬性,用于告訴瀏覽器某個元素在未來可能會發(fā)生哪些變化,本文給大家介紹CSS will-change 屬性詳解,感興趣的朋友一起看看吧2025-04-07
- 本文給大家分享在 CSS 中,去除a標(biāo)簽(超鏈接)的下劃線的幾種方法,本文給大家介紹的非常詳細,感興趣的朋友一起看看吧2025-04-07
- 在前端開發(fā)中,CSS(層疊樣式表)不僅是用來控制網(wǎng)頁的外觀和布局,更是實現(xiàn)復(fù)雜交互和動態(tài)效果的關(guān)鍵技術(shù)之一,隨著前端技術(shù)的不斷發(fā)展,CSS的用法也日益豐富和高級,本文將2025-04-07
css中的 vertical-align與line-height作用詳解
文章詳細介紹了CSS中的`vertical-align`和`line-height`屬性,包括它們的作用、適用元素、屬性值、常見使用場景、常見問題及解決方案,感興趣的朋友跟隨小編一起看看吧2025-03-26淺析CSS 中z - index屬性的作用及在什么情況下會失效
z-index屬性用于控制元素的堆疊順序,值越大,元素越顯示在上層,它需要元素具有定位屬性(如relative、absolute、fixed或sticky),本文給大家介紹CSS 中z - index屬性的作用2025-03-21- 文章詳細介紹了CSS中的打印媒體查詢@mediaprint包括基本語法、常見使用場景和代碼示例,如隱藏非必要元素、調(diào)整字體和顏色、處理鏈接的URL顯示、分頁控制、調(diào)整邊距和背景等2025-03-18
CSS模擬 html 的 title 屬性(鼠標(biāo)懸浮顯示提示文字效果)
本文介紹了如何使用CSS模擬HTML的title屬性,通過鼠標(biāo)懸浮顯示提示文字效果,通過設(shè)置`.tipBox`和`.tipBox.tipContent`的樣式,實現(xiàn)了提示內(nèi)容的隱藏和顯示,感興趣的朋友一起2025-03-10前端 CSS 動態(tài)設(shè)置樣式::class、:style 等技巧(推薦)
本文介紹了Vue.js中動態(tài)綁定類名和內(nèi)聯(lián)樣式的兩種方法:對象語法和數(shù)組語法,通過對象語法,可以根據(jù)條件動態(tài)切換類名或樣式;通過數(shù)組語法,可以同時綁定多個類名或樣式,此外2025-02-26