一、從哪裡說起呢…
數年前寫過一篇很實用的文章,介紹了一個很有創意的技術:“CSS背景色鏤空技術實際應用及進階”,講的圖示圖形為了更容易控制其顏色,對圖片採用了鏤空的處理。例如,下面這張圖片(點選會有隨機的背景色):
於是,我們只要一套圖片就可以實現各種顏色效果了!
而不要類似下面這樣,為了各種狀態湊齊完整的葫蘆七兄弟:
除了節約圖片資源大小,CSS鏤空圖片技術還有一個好處,就是由於我們的圖示顏色是CSS屬性控制的,因此,我們可以漸進使用transition實現過渡效果,讓互動更細膩。
說到CSS控制圖示顏色,我們自然而然會想到icon fonts, 或者使用SVG sprites技術,或者使用混合模式來實現。
然而,都是有不足的,比方說:
SVG的相容性以及混合模式的理解成本和環境限制等。
因此,轉了一圈,會發現,有時候,還是圖片來得最實在,且看下面demo實現的效果,雖然使用的是background-image實現的,但是hover
態,selected
態都和文字hover transition過渡,這是傳統背景圖片所沒法實現的。
您可以狠狠地點選這裡:鏤空背景圖片下的transition過渡效果
一行:
1 |
transition: background-color .25s; |
就可以讓互動變得細膩!
default, hover, selected三種顏色態僅僅一個系列圖片就搞定(見下圖),看上去很贊,贊到飛起來。
然而,這種實現有一個致命的不足,就是CSS的載入和背景圖片的載入不是同步的,尤其首次載入的時候,圖片是非同步的,具有明顯的延遲,於是,我們會看到非常醜陋的色塊在一瞬間出現了(大家可以強刷demo體驗到)!
正所謂“開發可忍設計不可忍”,這種問題顯然是非常嚴重的,直接導致此看上去很酷的方法瀕臨夭折的邊緣,看上去只適用於預設隱藏的元素。
大家莫慌莫慌,有我在呢!
二、base64 url圖片與非同步色塊問題解決
這個很好理解,就是把背景圖片轉換成base64 url圖片,因為是整合在CSS檔案中的,因此,基本上是同時呈現,不會出現色塊。然而,此方法侷限性很明顯,就是隻適用於一些尺寸很小的小圖。類似上面demo的背景圖片,有5K多大小,直接內嵌在CSS檔案中,就像是身體里長了個瘤子,太笨重了,而且base64渲染是比較燒效能的,圖片越大越慢,且IE7瀏覽器很難支援base64圖片。
因此,此方法在這裡不適用,難道要天亡我也?非也!
三、content url圖片與非同步色塊問題解決
6年前,也就是10年的時候,我在“CSS content內容生成技術以及應用”一文中首次介紹了CSS content
url圖片內容生成技術,就是before
, after
偽元素可以直接插入圖片,注意,是直接圖片,不是元素的背景圖,語法如下:
1 |
.demo:after { content: url(xxx.png); } |
OK, 大家如果觀察過頁面圖片的載入,應該注意到這麼個現象,就是如果圖片沒有通過HTML屬性或者CSS值限定width
/height
寬高的時候,在瀏覽器get到圖片的原始尺寸之前,圖片佔據的空間大小是0
. 我們如果重新整理浪微博,會發現頁面高度蹭蹭蹭地往上漲,就是這麼個原因,這種不對圖片限定尺寸的做法在網頁佈局中是不推薦的,因為,會造成頁面佈局重繪,影響載入效能。
但是,存在必有道理,在這裡,我們就可以好好地利用圖片為載入時候佔據空間為0
的特性避免出現色塊的問題,怎麼解決呢?就是把元素的background-image
url
值變成偽元素的content
url
值;同時background-position
定位改成其他定位,如relative
定位,如下程式碼示意:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
.icon { width: 140px; height: 140px; background: #c8c8c8 url(icon.png) no-repeat 0 -140px; } ↓ .icon { /* 注意,只設高度不設寬度 */ height: 140px; background-color: #c8c8c8; overflow: hidden; } .icon:after { content: url(icon.png); position: relative; top: -140px; } |
上面綠色註釋“只設高度不設寬度”點出了實現的關鍵:
頁面渲染流程如下,1. CSS載入;2. 對應DOM渲染,背景色出現;3.拉取DOM樣式對應背景圖片。
傳統實現就是從2到3的時候出現了問題,圖片從伺服器重新請求,導致了時間差,出現了色塊。而我們這裡的實現就不一樣,當我們背景色出現,但是圖片未載入的時候,由於我們的CSS沒有設定元素的寬度,加上圖片未載入佔據寬度為0的特性,於是,在2完成3即將進行的時候,我們整個元素的高度140px, 寬度0,寬度是0啊!這意味著什麼,意味著元素看不見啊,也即是雖然有背景色,無奈尺寸為0,我們是看不出有一絲絲背景色的;然後等圖片請求到,自然就填滿了元素,背景色也被遮掉了。沒有了時間差,於是,完美解決了色塊出現的問題!
您可以狠狠地點選這裡:content url生成的解決色塊問題demo
IE7瀏覽器
什麼年代了,還IE7瀏覽器,要是喜歡,可以使用expression表示式,或者直接JS打個補丁,小弟我現在對這些瀏覽器不奉陪了!
四、結束語
我測試發現,時間差似乎就Chrome瀏覽器比較明顯,另外後面的content
url
有一定機率會出現最後一個有色塊的情況,按照道理應該不會的,現在太晚了,都2點了,我有時間在研究研究。
- CSS背景色鏤空技術實際應用及進階 (0.695)
- 未來必熱:SVG Sprite技術介紹 (0.244)
- IE6下png背景不透明問題的綜合擴充 (0.225)
- CSS3圖示圖形生成技術個人攻略 (0.225)
- javascript HEX十六進位制與RGB, HSL顏色的相互轉換 (0.169)
- SVG圖示顏色文字般繼承與填充 (0.169)
- SVG-Morpheus實現SVG圖示圖形間的補形動畫 (0.169)
- CSS1-CSS3 顏色知識知多少? (0.169)
- 偽類+js實現CSS3 media queries跨界準確判斷 (0.136)
- CSS content內容生成技術以及應用 (0.097)
- 小tip: 某簡單的字元重疊與圖形生成 (RANDOM – 0.075)