使用CSS怎么實(shí)現(xiàn)毛玻璃特效?下面本篇文章給大家介紹一下使用CSS實(shí)現(xiàn)毛玻璃特效(兼容方案探究)的方法,希望對(duì)大家有所幫助!
前一段時(shí)間在某項(xiàng)目中用到了“高斯模糊”的濾鏡效果,過(guò)程中嘗試了多種方案,這里總結(jié)一種方式,希望可以幫助到有需要的道友~
UI 小姐姐非要讓我在 Android 系統(tǒng)自定義的 Webview 上支持實(shí)現(xiàn)我們俗稱的“毛玻璃”效果,說(shuō)是一定要實(shí)現(xiàn),不實(shí)現(xiàn)這種效果就失去了設(shè)計(jì)的靈魂,奈何我百般解釋,她就要,就要,要!
沒(méi)辦法,研究一下子咯!
【推薦學(xué)習(xí):css視頻教程】
一、backdrop-filter 是金手指嗎?
毛玻璃效果在 iOS 系統(tǒng)上比較常見(jiàn),比如消息通知欄、手機(jī)助手卡片等地方,所以咱打開(kāi)蘋果官網(wǎng)看看!
果不其然,導(dǎo)航欄就用到了“家族式設(shè)計(jì)”的“毛玻璃”特效
打開(kāi)控制臺(tái)抄一抄作業(yè):
主要是用到了 backdrop-filter
CSS3 的屬性,于是乎,順手就用上了。
主要的卡片 CSS 代碼如下:
.card-backdrop-filter { position: relative; z-index: 1; width: 600px; height: 300px; border-radius: 6px; padding: 10px; color: #fff; font-size: 16px; overflow: hidden; margin: 100px auto; backdrop-filter: blur(10px); background-color: rgba(255,255,255,0.72); }
在 Chrome 瀏覽器看著效果還可以:
然后再到某臺(tái)老 Android 版本的移動(dòng)端上看看,結(jié)果不行了!?。?/p>
去查了查兼容性:backdrop-filter — caiuse
emmm~,再考慮到我司自己魔改的 Webview 內(nèi)核情況。。。
需要再尋求另外的方式,這里補(bǔ)充一下子,filter 可以理解為濾鏡,backdrop-filter
就是給背景設(shè)置濾鏡效果,CSS 目前支持的濾鏡效果有
blur(): 模糊 brightness(): 亮度 contrast(): 對(duì)比度 drop-shadow(): 陰影 grayscale(): 灰度 hue-rotate(): 色相旋轉(zhuǎn) invert(): 反色 opacity(): 透明度 saturate(): 飽和度 sepia(): 褐色
如果不考慮兼容性,backdrop-filter
會(huì)在不支持的瀏覽器上直接顯示背景色,也就是失去設(shè)定的效果(“體驗(yàn)降級(jí)”)。
如果 UI 小姐姐和 PM 大哥能同意的話,也是非常推薦大家使用,畢竟誰(shuí)不想早下班學(xué)習(xí)吶?
二、filter 試一試?
另一個(gè)設(shè)置模糊度的 CSS 屬性就是 filter
,那么我們的另一個(gè)思路就是通過(guò) filter
來(lái)模擬 backdrop-filter
屬性的效果。
且 filter
的兼容性會(huì)更好:filter — caiuse
我們看看 filter
和 backdrop-filter
效果的差異:
/* filter 的寫(xiě)法,將 backdrop-filter 屬性替換為 filter */ .card-filter { position: relative; z-index: 1; width: 600px; height: 300px; border-radius: 6px; padding: 10px; color: #fff; font-size: 16px; overflow: hidden; /* 隱藏超出元素區(qū)域外的內(nèi)容 */ margin: 100px auto; filter: blur(10px); background-color: rgba(255,255,255,0.72); }
這效果和實(shí)際的設(shè)計(jì)需求大相徑庭,因此還需要改改!
三、filter 的組合拳
因?yàn)?filter
設(shè)置的是整個(gè)元素的模糊度,而不是做用于元素的背景容器,所以需要一個(gè)和卡片等大小的占位元素來(lái)單獨(dú)設(shè)置模糊度,并作為背景元素。
3.1 ::before + 固定雙背景圖
這里偷個(gè)懶,直接使用了偽元素 ::before
,實(shí)際場(chǎng)景為了考慮兼容性,建議大家還是用 div
塊級(jí)元素占位
.card-filter::before { content: ' '; position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: -1; /* 放到當(dāng)前 card-filter 元素的底部 */ filter: blur(10px); /* 模糊度 */ background: url(http://p2.qhimg.com/bdr/__85/t01781bd4b1218329e1.jpg) no-repeat center fixed; background-size: cover; }
這里注意到,卡片采用了和整個(gè)容器的背景圖屬性是一樣的,通過(guò) fixed
方式固定背景圖,這樣當(dāng)元素在任意方向滾動(dòng)的時(shí)候,背景圖不會(huì)移動(dòng),能保證背景效果是一致的
3.2 利用 margin 屬性的負(fù)值擴(kuò)大容器
模糊度的效果如下圖,還是有差異,因?yàn)?filter
是從容器外邊框向內(nèi)聚合的一個(gè)濾鏡,導(dǎo)致濾鏡外邊框有一個(gè)白圈
此時(shí)只需要擴(kuò)大 ::before
元素的容器大小,這里直接可使用 margin
屬性負(fù)值擴(kuò)大容器
.card-filter::before { ... + margin: -20px; }
此時(shí)的效果就有點(diǎn)“那個(gè)意思了”,看來(lái)快可以交差了
3.3 ::after 填補(bǔ)消失的背景色
原本設(shè)置在 .card-filter
類上的 background-color: rgba(255, 255, 255, 0.72);
沒(méi)起作用!
因?yàn)?::before
偽類作用于 .card-filter
元素內(nèi),是其子元素,又因?yàn)?::before
的 background
屬性設(shè)置了背景圖,遮蓋了父元素 .card-filter
的背景色。
知道了原因,那么我們就可以在 .card-filter
元素內(nèi)再添加一個(gè)子元素(偽類),用于設(shè)置背景色!
再偷個(gè)懶,直接使用 ::after
偽類,就不用改造 DOM 結(jié)構(gòu)。
.card-filter::after { content: ' '; position: absolute; top: 0; right: 0; bottom: 0; left: 0; z-index: -1; background-color: rgba(255, 255, 255, 0.72); }
此時(shí),效果就和 backdrop-filter
的效果相同:
放到“自研”的 Webview 內(nèi)核中也能看到效果了!
四、總結(jié)
總的來(lái)說(shuō),如果能說(shuō)服產(chǎn)品經(jīng)理和 UI 小姐姐的話,咱就用 backdrop-filter
,說(shuō)服不了就用 filter
的組合拳模擬吧!
另外 backdrop-filter
屬性是有性能問(wèn)題的,咱就是說(shuō),都 2022 年了,求求大家升級(jí)一下手上的設(shè)備吧!,兼容性真讓前端工程師禿頭兒!
如果“毛玻璃”和背景沒(méi)有文中的相對(duì)移動(dòng),直接讓 UI 小姐姐切個(gè)圖,直接解決一切兼容性 & 性能問(wèn)題!
在研究過(guò)程中,筆者還嘗試過(guò) SVG 的 feGaussianBlur
標(biāo)簽,效果和 filter
一樣,會(huì)稍微復(fù)雜一些,不過(guò)也是個(gè)可施行的方案,大家可自行嘗試下~
原文地址:https://juejin.cn/post/7070325873202692104
(學(xué)習(xí)視頻分享:web前端)