1. 程式人生 > >PNG格式小圖示的CSS任意顏色賦色技術

PNG格式小圖示的CSS任意顏色賦色技術

FROM: http://www.zhangxinxu.com/wordpress/2016/06/png-icon-change-color-by-css/

CSS可以修改圖片的顏色

程式碼:

CSS程式碼:
.icon {
    display: inline-block;
    width: 20px; height: 20px;
    overflow: hidden;
}
.icon-del {
    background: url(delete.png) no-repeat center;
}
.icon > .icon {
    position: relative;
    left:
-20px; border-right: 20px solid transparent; -webkit-filter: drop-shadow(20px 0); filter: drop-shadow(20px 0); }
HTML程式碼:
<p><strong>原始圖示</strong></p>
<i class="icon icon-del"></i>
<p><strong>可以變色的圖示</strong></p>
<i class="icon">
<i class="icon icon-del"></i></i>

上面的不是很黑的是原始圖示,是個PNG圖片,下面這個是可以賦色的:

可以變色的圖示

下面,我們隨意選擇一個顏色,例如紫色,然後:
紫色賦色

紅色賦色

是不是感覺很厲害!以後設計師就不需要在提供幾套顏色的圖片了。

SVG, icon fonts等技術似乎也不是那麼耀眼了。

二、原理其實很簡單

原理其實很簡單,使用了CSS3濾鏡filter中的drop-shadowdrop-shadow濾鏡可以給元素或圖片非透明區域新增投影。

對於背景透明的png小圖示而言,如果我們施加一個不帶模糊的投影,不就等同於生成了另外一個顏色的小圖示了嗎?

然後,我們把原始圖示隱藏在容器外面,投影圖示在容器中間,不見給人感覺是賦色效果了?

比方說本文的demo,如果把icon父級的的overflow:hidden去掉,原始的圖示就暴露出來啦!

去掉overflow:hidden之後

三、實現的時候實際有難度

原理如上面,我一開始實現的時候,以為很簡單,因為分分鐘可以實現自己的想法,後來發現有些天真了,Chrome瀏覽器怎麼都顯示不出來;FireFox瀏覽器卻可以!咦,究竟發生了什麼。

在Chrome瀏覽器下,drop-shadow有一個如下的呈現特性:

在Chrome瀏覽器下,如果一個元素的主體部分,無論以何種方式,只要在頁面中不可見,其drop-shadow是不可見的;實體部分哪怕有1畫素可見,則drop-shadow完全可見。

所以,我試過:

  • text-indent負值隱藏原始圖,無投影,失敗!
  • clip剪裁隱藏,無投影,失敗!
  • margin負值隱藏原始圖,無投影,失敗!
  • left負值隱藏原始圖,無投影,失敗!

通通不行,實現遇到了巨大的阻礙。

後來,靈光一現,如果我實體部分也在可視區域內,但是是透明的,會怎樣呢(反正不會有投影出來)?

於是,我就試了下曾經立下無數戰功的透明邊框,臥槽,又立功了,成了!

因此,下面這一個CSS宣告是千萬不能少的:

border-right: 20px solid transparent;

四、關於相容性

IE13+支援,Chrome和FireFox瀏覽器支援,移動端iOS支援,Android4.4+支援。也就是,基本上,移動端現在可以使用這種技術了。

既節約了流量,也讓我們的開發更簡單,維護更方便了。

CSS3 filter:drop-shadow濾鏡與box-shadow區別應用

要使用標準的CSS3實現某元素的投影效果,有兩個套路,第一個就是使用常見的box-shadow, 第二個就是使用CSS3的filter陰影濾鏡drop-shadow,那這兩個陰影實現有什麼具體的差異呢?

一、相容性不一

CSS3 box-shadow從IE9瀏覽器開始就支援了;
filter中的drop-shadowIE13才開始支援,移動端Android4.4才開始支援

二、同樣的引數值,表現效果有差異

filter中的drop-shadow語法如下:

filter: drop-shadow(x偏移, y偏移, 模糊大小, 色值);

例如:

filter:drop-shadow(5px 5px 10px black)

表示右下5畫素偏移,10畫素模糊的黑色陰影。眼見為實,看下面的圖片示意(實時效果,請使用Chrome或手機瀏覽器檢視):

但是,如果使用同樣引數值的box-shadow,例如:

box-shadow: 5px 5px 10px black;

會發現,box-shadow的陰影距離更小,色值要更深:

三、drop-shadow沒有內陰影效果

box-shadow支援inset內陰影,如:

box-shadow: inset 5px 5px 10px black;

但是,drop-shadow卻沒有。

四、drop-shadow不能陰影疊加

box-shadow有個超屌的特性,就是陰影可以任意累加,因此,理論上我們可以使用box-shadow生成任意的圖片,包括張含韻妹子年輕時候的寫真,具體可參加“CSS3 box-shadow盒陰影圖形生成技術”一文。

但是filter中的drop-shadow就只能抱歉了,我就是一錘子買賣。沒錢也這麼任性!

說到現在,體現的盡是drop-shadow的不好,相容性不夠,內陰影不支援,多陰影也不支援;感覺就像是小蚯蚓,失戀了,工作也沒了,存在的意義好像就成了白富美的談資。

真的是這樣嗎?顯然非也!所謂存在既有道理。

drop-shadow有一個很厲害的特性,也就這一個特性,讓其以後有足夠的機會大放異彩!那就是,drop-shadow才是真正意義上的投影,而box-shadow只是盒陰影而已。

什麼意思呢?

五、陰影 vs 盒陰影

實踐出真知,下面我們用CSS border寫一個虛線框,例如:

border: 10px dashed #beceeb;

結果長相如下:

然後,我們分別應用box-shadowdrop-shadow濾鏡:

border: 10px dashed #beceeb; box-shadow: 5px 5px 10px black;
border: 10px dashed #beceeb; filter: drop-shadow(5px 5px 10px black);

結果:

怎麼樣?是不是本性暴露了!

box-shadow顧名思意“盒陰影”,只是盒子的陰影;你想啊,這盒子中間明明是透明的,結果,陰影的時候,居然光線沒有穿透;但是drop-shadow就符合真實世界的投影,非透明的顏色,我就有投影;透明部分,光線穿過,沒投影,而什麼盒子不盒子的,跟我沒有任何關係。

drop-shadow不僅可以穿透程式碼構建的元素的透明部分,PNG圖片的透明部分也是可以穿透的,如下圖:

於是,曾經困擾我們的一些老大難的問題就有了很好的解決思路了!

六、drop-shadow的實際應用

我們實現帶有箭頭指向的浮層面板的時候,考慮到相容性,三角基本上都是使用border繪製的,沒法box-shadow,但是,矩形部分設計師希望是有陰影的,於是,就會出現下圖所示的情況:
沒有陰影的三角

箭頭沒有陰影,矇混過關。

後來,又搗騰了一個辦法,就使用矩形進行45deg旋轉,兩個box-shadow合體,但是,會存在陰影重疊的一部分,說穿了,還是效果不完美。

現在,有了drop-shadow,陰影就真的變成了陰影了。

CSS程式碼:
.box {
    margin: 40px; padding: 50px;
    background-color: #fff;
    position: relative;
    font-size: 24px;
}
.cor {
    position: absolute;
    left: -40px;
    widtd: 0; height: 0;
    overflow: hidden;
    border: 20px solid transparent;
    border-right-color: #fff;
}
.box-shadow {
    box-shadow: 5px 5px 10px black;
}
.drop-shadow {
    filter: drop-shadow(5px 5px 10px black);
}

HTML程式碼:
<div class="box box-shadow">
    <i class="cor"></i>
    box-shadow
</div>
<div class="box drop-shadow">
    <i class="cor"></i>
    filter: drop-shadow
</div>

一切盡在截圖中:
drop-shadow的實際應用效果截圖

七、結束語

低版本IE瀏覽器下,其實也有Shadow濾鏡,不過是IE的私有濾鏡。如果想要實現相容IE9+的投影效果,估計要藉助SVG來實現了。