1. 程式人生 > >騰訊乾貨!超實用的高清圖示SVG解決方案全總結2

騰訊乾貨!超實用的高清圖示SVG解決方案全總結2

在上一篇文章中,我們講述了字型渲染機制和導致iconfont出現鋸齒的原因,以及如何才能出繪製高質量SVGICON,並且提供了一套AI模版供大家參考使用。下文將講訴前端側我們如何用SVG來做成高清IOCN,並且良好支援PC下的各個瀏覽器,併兼容IE6+以上的瀏覽器。

從上一篇文章中我們得知SVG 做的圖示在IE9+的瀏覽器渲染效果相當的差,所以在IE下我們我們不使用SVG ICON,我們可以將SVG轉成一倍的png圖片來進行替代。首先來簡單的普及一下SVG ICON的幾個使用方法:

第一種Inline SVG

這種方法就是直接把SVG標籤寫入到HTML中去,直接通過修改fill和stroke屬性來控制填充顏色和邊框顏色,但是缺點就是維護性不好,如果一個頁面Icon特別多,可能要寫好幾十個SVG在頁面,複用性差,後期擴充套件性也不佳。

1
2
3
 <svg  width="74" height="74" viewBox="0 0 74 74">
    <path fill="#444444" d="M25.42 27.737v-11.555c0-6.382 5.174-11.555 11.555-11.555s11.555 5.174 11.555 11.555v11.555h4.622v-11.555c0-8.935-7.243-16.178-16.178-16.178s-16.178 7.243-16.178 16.178v11.555h4.622z"></path>
</svg>

第二種img/object 標籤

這種方法直接將SVG ICON儲存成一個一個單獨檔案,通過img或object標籤引用,他的缺點就是請求數增加,每個圖示都去獨自載入,對伺服器負載和頁面高速載入不好。

1
<img src="svg/16-16.svg" alt="test icon" />

第三種background and Data URIs

在上一篇文章中我有一種呼叫方法就是採用background去呼叫SVG檔案:

1
2
3
.icon {
  backgound-image: url(test.svg)
}

還有如果單獨使用background引用SVG也會和第一種方案一樣造成請求數增加,所以有不少人通過使用base64 編碼來減少HTTP請求:

1
2
3
.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進行定位,這種方法可以解決請求數增多的問題。

1
2
3
4
5
6
7
8
.icon {
    width: 16px;
    height: 16px;
    display: inline-block;
    background-repeat: no-repeat;
    background-image: url(sprite.svg);
     background-position: 0 0;
}

第五種SVG Defs/Symbols

這種其實就是在SVG Sprites上面更進一步的使用了,SVG Sprites是需要我們去通過座標獲取對應位置圖示的,但是SVG Defs/Symbols就更簡單了,直接通過給每個SVG ICON定義ID,直接呼叫對應ID即可:

1
2
3
4
5
6
7
8
<svg xmlns="http://www.w3.org/2000/svg">
    <symbol id="icon1" viewBox="0 0 32 32">
        <path fill="#444444" d="M3 3h1v12h-1v-12z"></path>
    </symbol>
    <symbol id="icon2" viewBox="0 0 32 32">
        <path fill="#444444" d="M3 14h10v1h-10v-1z"></path>
    </symbol>
</svg>

將上面程式碼儲存為SVG檔案後,在HTML我們通過下面的方式可以直接呼叫:

1
2
3
4
5
6
<svg>
    <use xlink:href="/svg/symbol.svg#icon1"></use>
</svg>
<svg>
    <use xlink:href="/svg/symbol.svg#icon2"></use>
</svg>

新的方案:Svg Sprites +Png Sprites + Image-set

由於我們知道SVG在IE下的相容性並不好,所以在高清ICON的適配在第四種方案的基礎上進行優化,首先用icomoon進行下面的步驟操作:

第一步將用AI模板做好的圖示轉換成SVG檔案後匯入到icomoon中:

高清ICON SVG解決方案(下)

第二步:

高清ICON SVG解決方案(下)

第三步,設定匯出檔案前的類名,圖示間距,顏色等等一系列引數,然後下載壓縮包:

高清ICON SVG解決方案(下)

第四步,只獲取我們所需要的資料夾的內容:

高清ICON SVG解決方案(下)

第五步,對icomoon生成的樣式sprite.css進行微調整讓其適配所有PC瀏覽器和Retina下的瀏覽器:

高清ICON SVG解決方案(下)

最後的效果:

高清ICON SVG解決方案(下)

CSS4 Image-set

這裡應該有人會覺得也可以使用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下所有瀏覽下,中間那個鎖的圖示雖然是用的生成的圖片但是依舊是發虛的和火狐下當時出問題的效果是一樣。