![]() |
VOOZH | about |
在上一篇文章中,我們講述了字體渲染機制和導致iconfont出現鋸齒的原因,以及如何才能出繪製高質量SVG ICON,並且提供了一套AI模版供大家參考使用。下文將講訴前端側我們如何用SVG來做成高清ICON,並且良好支持PC下的各個瀏覽器,併兼容IE6+以上的瀏覽器。
上期回顧:《高清圖標SVG解決方案全總結(上)》
我們得知SVG 做的圖標在IE9+的瀏覽器渲染效果相當的差,所以在IE下我們我們不使用SVG ICON,我們可以將SVG轉成一倍的png圖片來進行替代。首先來簡單的普及一下SVG ICON的幾個使用方法:
第一種Inline SVG這種方法就是直接把SVG標籤寫入到HTML中去,直接通過修改fill和stroke屬性來控制填充顏色和邊框顏色,但是缺點就是維護性不好,如果一個頁面Icon特別多,可能要寫好幾十個SVG在頁面,復用性差,後期擴展性也不佳。
第二種img/object 標籤
這種方法直接將SVG ICON保存成一個一個單獨文件,通過img或object標籤引用,他的缺點就是請求數增加,每個圖標都去獨自加載,對伺服器負載和頁面高速加載不好。
第三種background and Data URIs
在上一篇文章中我有一種調用方法就是採用background去調用SVG文件:
.icon { backgound-image: url(test.svg) }還有如果單獨使用background引用SVG也會和第一種方案一樣造成請求數增加,所以有不少人通過使用base64 編碼來減少HTTP請求:
.icon{ background: url(data:text/svg+xml;base64,) }不過不太建議使用base64 編碼,無論性能和維護方面都不是特別好,記得看過一個測試base64性能的文章,base64在移動端渲染時間比正常使用url的渲染時間要慢6倍。
第四種SVG Sprites目前市面上有很多提供ICON FONT製作的網站,例如:icomoon不止開源,而且功能實在強大,可以提供輸出SVG Sprites的功能,SVG Sprites它的使用方法其實就跟Png sprites是一樣的,把多個SVG ICON合併到一個SVG文件裡面去,然後通過background-position進行定位,這種方法可以解決請求數增多的問題。
.icon { width: 16px; height: 16px; display: inline-block; background-repeat: no-repeat; background-image: url(sprite.svg); background-position: 0 0; }當然如果你不喜歡用icomoon也可以用自動化工具生成SVG Sprite例如用:gulp-svgstore、grunt-iconizr、gulp-svg-sprites
第五種SVG Defs/Symbols這種其實就是在SVG Sprites上面更進一步的使用了,SVG Sprites是需要我們去通過坐標獲取對應位置圖標的,但是SVG Defs/Symbols就更簡單了,直接通過給每個SVG ICON定義ID,直接調用對應ID即可:
將上面代碼保存為SVG文件後,在HTML我們通過下面的方式可以直接調用:
由於我們知道SVG在IE下的兼容性並不好,所以在高清ICON的適配在第四種方案的基礎上進行優化,首先用icomoon進行下面的步驟操作:
第一步將用AI模板做好的圖標轉換成SVG文件後導入到icomoon中:
第二步:
第三步,設置導出文件前的類名,圖標間距,顏色等等一系列參數,然後下載壓縮包:
第四步,只獲取我們所需要的文件夾的內容:
第五步,對icomoon生成的樣式sprite.css進行微調整讓其適配所有PC瀏覽器和Retina下的瀏覽器:
最後的效果:
這裡應該有人會覺得也可以使用Media Queries來進行判斷處理在Retinal來加載SVG Sprites,但其實Image-set它和Media Queries有些許,它不需要告訴瀏覽器使用什麼圖像,而是直接提供了圖像讓瀏覽器自己去選擇加載合適的圖片。兼容性方面在Safari6.1開始和Chrome21就開始支持這個屬性了。
總結SVG目前還是存在許多問題,Windows下使用IE的兼容性和渲染效果都太差,在PC側我們無法全量使用,所以我們可以用上面的這套解決方案解決PC下所有瀏覽器下兼容問題,在Retina下,不管是device =2還是3都可以兼容,不管未來是否會有更高的devicePixelRatio出來,按照上面的方法都能完美兼容,並且在對應不同的devicePixelRatio下瀏覽器會自動選擇加載SVG或者PNG,不會兩張都同時加載。
上一篇文章之所以在火狐圖標出問題那塊講了許久,並拋出更嚴謹的圖標製作方法的主要原因這個方案需要對合併後的SVG Sprites轉成PNG Sprite圖片,如果SVG ICON做的有問題,那生成的圖片也然出現發虛的情況,大家看我最後那個效果圖下,PC下所有瀏覽下,中間那個鎖的圖標雖然是用的生成的圖片但是依舊是發虛的和火狐下當時出問題的效果是一樣。