CSS 如何根據(jù)背景色自動切換黑白文字?
在項目中,經(jīng)常會碰到背景色不確定的場景,為了讓內(nèi)容文字足夠清晰可見,文字和背景之間需要有足夠的對比度。換句話說,當背景是深色時,文字為白色,當背景是淺色時,文字為黑色,就像這樣:
通常這種情況,大家可能會通過 js 去計算背景色的深淺度(灰度),算法是公開的,如果已知顏色的??RGB?
?值,那么可以通過以下方式得到顏色灰度
這樣可以得到一個0~1之間的范圍值,可以根據(jù)需求,設(shè)定一個閾值,超過表示為淺色,否則為深色。
原理就是這樣,這里就不多介紹了。
那么,純 CSS 也能實現(xiàn)這樣的效果嗎?當然可以,而且實現(xiàn)更簡單,一起看看吧。
一、CSS 濾鏡實現(xiàn)
實現(xiàn)這個效果需要用到 CSS 濾鏡。
假設(shè)有 HTML 是這樣的。
因為要使用濾鏡對文字單獨處理,所以需要額外一層標簽。
然后,容器和文字用同一種顏色表示,目的是讓文字顏色和背景相關(guān)聯(lián),可以通過currentColor實現(xiàn)。
接下來可以想一下,如何讓彩色文字變成黑白?
提到黑白,可以想到灰度濾鏡(grayscale),相信大家前幾天都用到過,這樣可以將彩色的文字轉(zhuǎn)換成灰色。
效果如下:
這樣文字顏色由原來的黃綠色變成了淺灰色。
但是,這種灰色在現(xiàn)在這種背景下太難看清了,我們需要的是純正的黑色或者白色,現(xiàn)在只是灰色,如何“加強”一下呢?
這時,我們可以用到對比度濾鏡(contrast),在前面的基礎(chǔ)上再疊加一層。
這里的對比度給的比較大,這樣就會極大的增強對比度,黑的更黑,白的更白,如果是淺灰,那就變成白色,如果是深灰,那就變成黑色,效果如下:
這樣能還不太明顯,我們把背景色換一下。
最后,還差一步,由于前面的操作是將原有顏色經(jīng)過濾鏡轉(zhuǎn)換成了和自身相對應(yīng)的白色或者黑色,但是是相反的,所以需要用到反轉(zhuǎn)濾鏡(invert),顛倒黑白。
效果如下:
下面用一張圖來表示轉(zhuǎn)換過程:
下面是任意顏色的適配效果,還是挺完美的。
代碼很簡單,就這么一行:
完整代碼可以查看以下任意鏈接
- CSS auto-color (juejin.cn)[1]
- CSS auto-color (codepen.io)[2]
- CSS auto-color (runjs.work)[3]
二、CSS 其他思路
除了上面這種方式,還可以通過 CSS 變量來實現(xiàn),要復(fù)雜一些。
這里簡單介紹一下實現(xiàn)思路:
- 將顏色RGB值拆分成 3 個獨立的 CSS變量。
- 通過灰度算法,用 CSS 計算函數(shù)算出灰度。
- 用得到的灰度和閾值做差值,通過hsl模式轉(zhuǎn)換成純黑和純白。
有興趣的可以參考張鑫旭老師的這篇文章:CSS前景背景自動配色技術(shù)簡介[4],可以看到,整體實現(xiàn)和 js 邏輯幾乎是一致的,下面是完整實現(xiàn)。
效果如下:
相比前面的實現(xiàn)而言,實現(xiàn)更加靈活,可以少一層標簽。
另外,CSS 正在起草一個顏色對比函數(shù)color-contrast,可以從幾個顏色中自動選擇對比度最高的那個,實現(xiàn)是這樣的。
不過,現(xiàn)在還沒有任何瀏覽器支持。
如果將來支持了,這將是終極解決方案。
三、優(yōu)缺點總結(jié)
總的來說,在color-contrast函數(shù)支持之前,我更推薦 CSS 濾鏡方式,有以下幾點好處
- 代碼簡潔,就一行代碼,3 個濾鏡。
- 對顏色格式無任何要求,無需轉(zhuǎn)換成RGB模式。
- 無需了解顏色算法,對設(shè)計更為友好。
當然,也是存在一些缺點
- 需要單獨一層標簽,使用場景可能有限制。
- 對顏色敏感度較高,不然無從下手。
- 顏色轉(zhuǎn)換有限制,最終只能是黑白,其他顏色就無能為力了。
下面來回顧一下用到的3個濾鏡,總結(jié)一下:
- 灰度濾鏡(grayscale),可以將彩色的文字轉(zhuǎn)換成灰色。
- 對比度濾鏡(contrast),可以極大的增強對比度,黑的更黑,白的更白,如果是淺灰,那就變成白色,如果是深灰,那就變成黑色。
- 反轉(zhuǎn)濾鏡(invert),可以翻轉(zhuǎn)顏色,顛倒黑白。
重新體會顏色轉(zhuǎn)換過程:
參考資料
[1]CSS auto-color (juejin.cn): ??https://code.juejin.cn/pen/7180639403566448698。
[2]CSS auto-color (codepen.io): ??https://codepen.io/xboxyan/pen/bGjVbGj。
[3]CSS auto-color (runjs.work): ??https://runjs.work/projects/bb844abe80da401d。
[4]CSS前景背景自動配色技術(shù)簡介: ??https://www.zhangxinxu.com/wordpress/2018/11/css-background-color-font-auto-match/。