深入理解CSS background-blend-mode的作用機制

2021-03-02 前端大學

(給前端大學加星標,提升前端技能.)

作者:張鑫旭

https://www.zhangxinxu.com/wordpress/2020/07/css-background-blend-mode/

一、可能都知道的

首先,講兩點大家可能都知道的知識點:

background-blend-mode本身就帶有隔離特性,也就是一個元素應用background-blend-mode背景混合模式,最終的效果只會受當前元素的背景圖像和背景顏色影響,不會受視覺上處於當前區域其他任意元素影響。

應用background-blend-mode屬性後,不僅各個圖像之間要進行混合,同時還要和背景色進行混合。

接下來,講下大家可能並不知道的知識點,這也是很多人搞不清楚為什麼background-blend-mode屬性這麼渲染的原因。

二、可能不知道的1. 背景順序影響混合效果

混合效果和background屬性中背景圖像的順序密切相關。在CSS多背景中,越是語法中靠後的背景圖像的層級越是低,這也是為何background-color要寫在最後語法才合法的原因,因為背景色的層級永遠是最低的。

例如下面2個元素:

<div></div><div></div>

設置背景混合模式為疊加,但是兩個元素的背景圖像的順序是相反的,代碼如下所示:

.ball {    width: 200px; height: 200px;    border-radius: 50%;    background: linear-gradient(deeppink, deeppink), linear-gradient(deepskyblue, deepskyblue);    /* 應用疊加混合模式 */    background-blend-mode: overlay;}.ball2 {    width: 200px; height: 200px;    border-radius: 50%;    background: linear-gradient(deepskyblue, deepskyblue), linear-gradient(deeppink, deeppink);    /* 應用疊加混合模式 */    background-blend-mode: overlay;}

結果下圖所示,.ball元素表現為deeppink疊加後面的deepskyblue,最終混合顏色偏藍;.ball2元素表現為deepskyblue疊加後面的deeppink,最終混合顏色偏紫。

2. 混合效果是多個混合屬性同時作用的結果

很多開發人員並不清楚,background-blend-mode支持其實是可以設置多個混合模式值,分別對應不同的背景圖像,這一點和僅僅支持一個混合模式值的mix-blend-mode屬性是不一樣的。例如:

.ball {    background: linear-gradient(deeppink, deeppink),        linear-gradient(deepskyblue, deepskyblue);    background-blend-mode: overlay;}

實際上等同於:

.ball {    background: linear-gradient(deeppink, deeppink),        linear-gradient(deepskyblue, deepskyblue);    background-blend-mode: overlay overlay;}

也就是,deeppink實際上疊加的是deepskyblue和背景色(此例是透明),deepskyblue疊加的是背景色(此例是透明)。

換言之,實際上,每個背景圖像都有一個自己的混合模式值,這是和mix-blend-mode屬性有著巨大區別的!通常,在使用mix-blend-mode屬性的場景中,我們只會把混合模式設置在頂層元素上,而不會每一層元素都設置,於是帶來了一個由此及彼的嚴重的思維誤區,以為背景混合模式設置的值也是作用在對頂層的背景圖像上的,從而導致很多開發者想不通background-blend-mode屬性的渲染表現和自己預期的不一樣。

我們通過一個案例演示下background-blend-mode屬性的多個值是如何和背景圖像一一對應的。

.box {    width: 200px; height: 200px;    background: linear-gradient(to right bottom, deeppink 50%, transparent 50%),        linear-gradient(to top right, deeppink 50%, transparent 50%),        darkblue;    background-blend-mode: multiply, screen;    position: relative;}/* 中間原始的deeppink色值 */.box::before {    content: '';    position: absolute;    width: 33%; height: 33%;    inset: 0;    margin: auto;    background-color: deeppink;}

此時.box元素總共呈現出了5種顏色,每種顏色的RGB色值和如何產生的如下圖所示。

其中:

中間標註了序號①的正方形區域沒有應用任何混合模式,顏色就是deeppink,作用是方便大家和區域③、區域⑤處的顏色進行對比。

區域②就是背景色darkblue,因為兩個斜向漸變均沒有覆蓋到這個區域,直接暴露了設置的背景色。

區域③和區域⑤是下層漸變,也就是background屬性值中位置靠後的漸變,對應的混合模式也是background-blend-mode屬性值靠後的那個,也就是screen,濾色模式,可以讓顏色變亮。

區域④和區域⑤是上層漸變,也就是background屬性值中位置靠前的漸變,對應的混合模式也是background-blend-mode屬性值靠前的那個,也就是multiply,正片疊底模式,可以讓顏色變暗。

區域③的顏色表現源自漸變色deeppink和背景色darkblue進行濾色混合的效果,可以看出最終呈現的顏色比deeppink更亮了,最終混合後的色值是rgb(255,20,206)。

區域④的顏色表現源自漸變色deeppink和背景色darkblue進行正片疊底混合的效果,可以看出最終呈現的顏色比darkblue更深了,最終混合後的色值是rgb(0,0,80)。

區域⑤最複雜,理解了這個,也就理解了大多數的background-blend-mode屬性的渲染表現了。

區域⑤總共有3層,分別是:上層的deeppink,混合模式是multiply;下層的deeppink,混合模式是screen;底層的背景色darkblue。

於是,最終的色值表現是上層的deeppink使用multiply混合下層的deeppink和背景色darkblue使用screen混合後的色值。

由於下層的deeppink和背景色darkblue使用screen混合後的色值就是區域③的顏色。因此,區域⑤的顏色就是deeppink和區域③的色值rgb(255,20,206)進行正片疊底混合後的色值,結果是rgb(255,1,119)。

以上就是.box元素5個顏色各自呈現的原理所在。

三、background-blend-mode與漸變圖標的實現

最後再看看看,為何大多數人沒辦法使用background-blend-mode實現漸變圖標的效果。

例如,現在有1個顏色很深的刪除小圖標,理論上,我們可以使用lighten混合模式實現漸變效果,因為lighten的效果是哪個顏色淺使用哪個顏色,由於圖標本身顏色很深,因此,一定會顯示漸變色,只要給圖標加一個白色底就可以,於是,按照這個思路,很多人就寫了如下所示的CSS代碼:

.icon-delete {    background: linear-gradient(deepskyblue, deeppink),        url(delete.png), white;    background-blend-mode: lighten;}

乍一看,似乎邏輯上無懈可擊,漸變和白底黑色的圖標進行變亮混合,怎麼想黑色圖標也應該變成漸變色啊,很遺憾,最終的漸變並不是漸變色,而是純白色,為什麼會有這樣的結果呢?

那是因為這裡的background-blend-mode:lighten實際上是一個縮寫,或者簡寫,實際上真實的計算值是lighten lighten,代碼如下所示:

.icon-delete {    background: linear-gradient(deepskyblue, deeppink),        url(delete.png), white;    /* 實際上的計算值 */    background-blend-mode: lighten lighten;}

也就是刪除圖標delete.png也應用了混合模式lighten,和白色背景色進行了混合,於是變成了純白色。

知道了問題所在,也就知道了該如何解決了,很簡單,讓delete.png和白色背景色混合後還保持原始圖標的模樣即可,下面兩種CSS方法均可以:

.icon-delete {    background: linear-gradient(deepskyblue, deeppink),        url(delete.png), white;    /* PNG圖標的混合模式單獨設成darken */    background-blend-mode: lighten darken;}

或者是:

.icon-delete {    background: linear-gradient(deepskyblue, deeppink),        url(delete.png), white;    /* PNG圖標的混合模式單獨設成normal */    background-blend-mode: lighten normal;}

推薦使用normal關鍵字,因為更巧妙,性能也更好一點。最終實現的效果如下圖所示。

當然,漸變圖標效果最好的實現方法肯定是CSS mask遮罩屬性,這裡的使用混合模式實現的漸變圖標會有白色的底,並不是完美的實現方法,主要目的還是讓大家了解background-blend-mode屬性的渲染細節。

四、background-blend-mode的補全規則

當background-blend-mode的屬性值的數量和background-image不匹配的時候,遵循下面的應用規則:

.example {    background: linear-gradient(deepskyblue, deeppink), white;    background-blend-mode: lighten;}

.example {    background: linear-gradient(deepskyblue, deeppink), white;    background-blend-mode: lighten, darken;}

如果background-blend-mode的值的數量少於background-image,則會重複完整的background-blend-mode屬性值進行補全,例如:

等同於:

也就是lighten, darken一起進行重複,而不是僅僅重複最後一個混合模式值。因此,補全的值的lighten。

.example {    background: linear-gradient(deepskyblue, deeppink),        linear-gradient(deepskyblue, deeppink),        linear-gradient(deepskyblue, deeppink), white;    background-blend-mode: lighten, darken, lighten;}

.example {    background: linear-gradient(deepskyblue, deeppink),        linear-gradient(deepskyblue, deeppink), linear-gradient(deepskyblue, deeppink), white; background-blend-mode: lighten, darken;}   

五、結語

CSS background-blend-mode屬性可以讓各個背景圖像之間應用混合模式。

background-blend-mode屬性的使用頻率要明顯低於mix-blend-mode屬性。

原因在於:

真實世界的照片圖像很少作為background-image背景圖像呈現,因為不利於無障礙訪問,而混合模式設計的初衷就是這類照片圖像的處理;

background-blend-mode屬性作用機制不像mix-blend-mode屬性那麼單純,很多開發人員並不能很好地駕馭。例如請使用混合模式讓透明背景的小圖標變成漸變圖標,使用mix-blend-mode屬性實現的人有很多,但是能夠使用background-blend-mode屬性實現的人寥寥無幾。

因此,目前background-blend-mode屬性更常見的應用是用來豐富CSS的背景紋理,例如:

具體就不展開,非本文主要內容。

以上就是本文的全部內容,感謝閱讀,如果你覺得內容還不錯,歡迎分享。

分享前端好文,點亮 在看 

相關焦點

  • CSS奇思妙想 -- 使用 background 創造各種美妙的背景
    關於混合模式的一些基礎用法,你可以參考我的這幾篇文章:不可思議的顏色混合模式 mix-blend-mode [3]不可思議的混合模式 background-blend-mode[4]然後,我們來嘗試第一個圖案,先簡單體會一下 mix-blend-mode 的作用。
  • 深入理解CSS中的層疊上下文和層疊順序
    而要理解網頁中元素是如何「論資排輩」的,就需要深入理解CSS中的層疊上下文和層疊順序。我們大家可能都熟悉CSS中的z-index屬性,需要跟大家講的是,z-index實際上只是CSS層疊上下文和層疊順序中的一葉小舟。一、什麼是層疊上下文層疊上下文,英文稱作」stacking context」.
  • 即將來到: CSS Feature Queries (CSS特性查詢)
    @supports (background-blend-mode: multiply) {    body {    background-blend-mode: multiply;    background: linear-gradient(rgb(59, 89, 106)    , rgb(63, 154, 130))    , url(background.png)
  • 10 個 GitHub 上超火的 CSS 技巧項目,找到寫 CSS 的靈感!
    包含了:布局(Layout)、陰影(box-shadow、drop-shadow)、偽類/偽元素、濾鏡(fliter)、邊框(border)、背景/漸變(linear-gradient/radial-gradient/conic-gradient)、混合模式(mix-blend-mode/background-blend-mode)、3D、動畫
  • 前端學習——匯集了大量 CSS 的使用和學習的示例代碼
    conic-gradient)線性漸變實現條紋字重複徑向漸變實現波浪邊框漸變實現波浪效果/波浪進度框漸變實現優惠券波浪造型線性漸變實現內切直角線性漸變實現箭頭符號利用線性漸變實現下劃線使用 background-attachment
  • 第四代CSS選擇器,那些讓你激動的新特性
    在接下來的CSS中,我們使用了帶有背景圖像的選擇器.box,通過設置background-color為red,background-blend-mode為hue和multiply,我給圖片增添了有趣的效果。
  • 神奇的 CSS3 混合模式
    CSS3 mix-blend-mode 和 background-blend-mode本節主要講下css3混合模式的mix-blend-mode和background-blend-mode兩個屬性,兩個屬性的取值是一樣的,不一樣的是:引題的小例子就是用的mix-blend-mode屬性,實現的是文本和背景圖的混合。
  • 高級前端開發工程師總結:8個不可錯過的CSS開發工具
    這是因為我們沒有遵循適當的學習流程,因此我們很難理解CSS的行為。本文旨在通過兩種方式為你提供CSS的學習幫助:藉助專用工具對CSS進行編碼以及通過一些交互環境學習CSS,下面和千鋒廣州小編一起來看看吧!
  • 前端進階:css必知的幾個底層知識和技巧
    在介紹完問題學習法之後,進入我們今天的主題,接下來我會介紹css的一些底層的知識的現象,藉此來讓大家對css有更深入的理解。如下案例所示:三.深入理解content1.在web中,很多替換元素在沒有明確尺寸設定的情況下,其默認的尺寸(不包含邊框)為300*150,如video,iframe,canvas等,少數為0,如img,而表單元素的替換尺寸和瀏覽器自身有關。
  • CSS背景屬性Background詳解
    css2 中的背景(background)CSS2 中有5個主要的背景(background)屬性,它們是:background-color: 指定填充背景的顏色。background-image: 引用圖片作為背景。background-position: 指定元素背景圖片的位置。
  • 前端基礎篇之CSS世界
    我想你每天寫css代碼有時候也會覺得很痛苦:這個布局的css怎麼這麼難實現!我也經常會有這種感覺,一個看似簡單的布局總是要琢磨半天才能實現,偶爾還會出現一些怪異的超出理解的現象。這是因為我們對css只是大概知道個形,並沒有看透css的本質。在同事的推薦下我閱讀了張鑫旭老師的《css世界》,才發現css跟想像中的不太一樣。
  • 前端進階: css必知的幾個底層知識和技巧
    在介紹完問題學習法之後,進入我們今天的主題,接下來我會介紹css的一些底層的知識和比較詭異的現象,藉此來讓大家對css有更深入的理解。一.css尺寸1.首選最小寬度–實現複雜圖形效果在css中,圖片和文字的權重遠大於布局,因此當width:0時表現出來的寬度就是「首選最小寬度」。中文的最小寬度為每個漢字的寬度,西方文字取決於連續的英文字符單元。
  • 我發現了7個關於 CSS backgroundImage 好用的技巧
    background-size: cover; -webkit-background-size: cover; -moz-background-size: cover; -o-background-size: cover;}事例源碼:https://codepen.io
  • Html+Css3
    :red  背景顏色background:transparent  透視背景background-image : url(/image/bg.gif)  背景圖片background-repeat : repeat  重複排列-網頁默認background-repeat : no-repeat  不重複排列background-repeat
  • CSS文字處理實用小技巧總結
    一份良好的代碼能讓人耳目一新,讓人容易理解,同時也讓自己成就感滿滿。因此,在這裡簡單的整理一些CSS開發技巧,希望能讓你寫出耳目一新、容易理解、舒服自然的代碼。CSS實用技巧第一講:文字處理本小結主要是圍繞css對文字處理的技巧,有興趣的小夥伴可以收藏一下。
  • 深入理解CSS:font metrics, line-height 以及 vertical-align
    懷疑是知識的鑰匙來源:http://zcfy.baomitu.com/article/deep-dive-css-font-metrics-line-height-and-vertical-align-vincent-de-oliveira-2616.html原文:http://iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align
  • CSS常用技巧介紹
    還有background,border等等.1.       關於background的寫法DIV.comment{background:#f0f0f0 url(url address) repeat-x left top}1)您可以看到background的第一個定義是一個顏色值這表示在背景圖片失效的時候顏色將起作用。
  • 前端開發必備的CSS命名規範與常用CSS代碼集合
    ,style.css主要的module.css模塊base.css基本共用layout.css布局,版面themes.css主題columns.css專欄font.css文字、字體forms.css表單mend.css補丁print.css列印三、藉助翻譯工具如果遇到不常用的一些名稱,可以藉助翻譯工具進行翻譯取其英文命名。
  • 面試必備 css面試必考點
    */}.box>div{ background: green; width: 200px; height: 200px;}7 display有哪些值?說明他們的作用?之前寫三角形, 都是直接記住代碼,沒有探究原因,我也是直到有一次面試時,面試大哥讓我說說css創建三角形的原理,我就.回來就趕緊翻資料.接下來我就將當時我理解的過程列舉出來:(1) 寫一個我們最熟悉的 border應用.box{ width:100px; height
  • CSS 背景(background)
    background-color 背景顏色background-image 背景圖片地址background-repeat 是否平鋪background-position 背景位置background-attachment 背景固定還是滾動