http://muki.tw/tech/css-to-svg-sprite/
Web Icon Font (簡稱 icon font):
https://www.oxxostudio.tw/articles/201406/css-icon-font.html
未来必热:SVG Sprite技术介绍
https://www.zhangxinxu.com/wordpress/2014/07/introduce-svg-sprite-technology/
SVG 的使用細節:
http://www.ruanyifeng.com/blog/2018/08/svg.html
https://zhuanlan.zhihu.com/p/25016633
https://github.com/YIXUNFE/blog/issues/31
https://www.oxxostudio.tw/articles/201410/svg-tutorial.html
CSS Sprite:
可以有效減少 HTTP 需求,但他終究是圖片,只要把網站等比放大,圖片就可能會失真。在現今螢幕解析度提高,以及 RWD 網站盛行的環境下,用 CSS sprite 要面對的可能就是這種失真的小瑕疵。
另外一個比較惱人的困擾,就是要把所有的 icon 排在同一張圖片,再自己算出定位,其實很麻煩。雖然可以使用 compass 這樣的 CSS 預處理器幫忙,但也不是所有人都用 compass 啊。
Web Icon Font:
好處是解決了「失真」的困擾,因為即使放大縮小,它的本質還是文字,文字放大縮小是不會失真的,可以保持它原有的清晰度。
但困擾來了,正因為他是文字,所以必須乖乖遵守文字的規範,我們常碰到的問題就是在「鋸齒」與「抗拒齒」之間徘徊,通常瀏覽器都會替文字進行抗拒齒的優化,以免放大閱讀文字時,會有凹凸不平的鋸齒狀,有的時候,某些圖標我們需要這些鋸齒,但另外一些圖片我們需要抗鋸齒,線段類的圖案、圓弧狀的圖案 … 等等,會依照不同的樣式有不同的需求。
Icon font 還有其他不方便的地方,例如受到 font-size, line-height 等等字型屬性的限制。一次要載入上百張 Icon font 的字型檔,但實際上用到的只是那幾張小圖,浪費了讀取的時間。最後還有一點是各家的 Icon font 整合不易。
補充資料:
Icon Font 導入 SVG 後,開始支援彩色圖標,通過一些技巧,支持像字體那樣,可以通過 font size 或 color 來微調。
IcoMoon,他是一個整合眾家 Icon font 的網站,此外也支援 SVG 匯出。
SVG sprite:
在講 SVG sprite 之前,需要先簡單講一下什麼是 SVG。SVG 簡單講就是用程式碼畫圖,這句話傳達了兩個意思:一、你必須要寫程式碼;二、他是不會失真的向量圖。
SVG 圖片所有的線段(<path>)都是寫在 HTML 裡面,然後再利用 CSS 屬性去修改它的顏色、大小等樣式。
每一張圖片都有一個自己的 <path> 或者 <circle> 等屬性,通常會寫在網頁的最上方,再利用<use xlink:href="#icon-video-camera"></use>呼叫。
雖然使用 SVG 可以有效解決解析度、鋸齒 等等問題,但如果要載入多張不同的圖片,程式碼會拖得很長。為了解決這個問題,我們可以改用 SVG sprite,也就是將所有圖片存在 SVG 檔案,再從 HTML 呼叫他。
SVG sprite 實作
以 IcoMoon 網站為例,先選好你要的圖片,在匯出 SVG 之前勾選 Include Tiles (CSS Sprite)
解壓縮之後,找到sprite/目錄,裡面有一個sprite.svg,原理就跟 sprite.png 一樣,會把所有圖案排列整齊,差別在於它是向量圖,放大縮小都不會失真。
接下來只要在 HTML 載入這張 SVG 檔案,並且透過ID去呼叫對應的 icon 就可以了。
<svg class="icon" xmlns="http://www.w3.org/2000/svg">
<use xlink:href="sprite.svg#icon-facebook"></use>
</svg>
<svg class="icon" xmlns="http://www.w3.org/2000/svg">
<use xlink:href="sprite.svg#icon-feed"></use>
</svg>
在 xlink:href 的地方,輸入這個 svg 檔案的相對路徑,後面再寫 ID 即可,跟 CSS sprite 相比是不是簡單許多呢。我們不需要再寫 background-position 去調整他的位子,往後要新增其他的 icon,直接打開 sprite.svg 編輯就可以了!
使用 IcoMoon 的 SVG sprite 注意事項:
IcoMoon 可以直接提供我們 SVG 的 path 程式碼,而且可以個別匯出,但如果想用 IcoMoon 做 SVG sprite,需要特別注意一件事情,就是可能需要自行修改它的 SVG 檔案。
什麼意思呢?因為 IcoMoon 把 icon 的顏色、大小都寫死在 SVG 檔案裡,這恐怕不是很好的管理方式。
以icon-facebook為例,IcoMoon 是這樣寫的:
<svg id="icon-facebook" width="32" height="32" viewBox="0 0 32 32" x="48" y="0">
<path fill="#444444" d="M26.667 0h-21.334c-2.945 0-5.333 2.388-5.333 5.334v21.332c0 2.946 2.387 5.334 5.333 5.334h10.667v-14h-4v-4h4v-3c0-2.761 2.239-5 5-5h5v4h-5c-0.552 0-1 0.448-1 1v3h5.5l-1 4h-4.5v14h6.667c2.945 0 5.333-2.388 5.333-5.334v-21.332c0-2.946-2.387-5.334-5.333-5.334z"></path>
</svg>
以下則是建議修改後的版本:
<svg>
<symbol id="icon-facebook" viewBox="0 0 32 32">
<path d="M26.667 0h-21.334c-2.945 0-5.333 2.388-5.333 5.334v21.332c0 2.946 2.387 5.334 5.333 5.334h10.667v-14h-4v-4h4v-3c0-2.761 2.239-5 5-5h5v4h-5c-0.552 0-1 0.448-1 1v3h5.5l-1 4h-4.5v14h6.667c2.945 0 5.333-2.388 5.333-5.334v-21.332c0-2.946-2.387-5.334-5.333-5.334z"></path>
</symbol>
</svg>
可以發現改用 <symbol> 管理 icon,並且移除了他們固定的樣式,當然要更加結構化,可以再加上<title>或<def>等標籤。
重點在於,如果不把 IcoMoon 寫的樣式移除,我們將無法用 CSS 控制這些樣式,所以請特別記住這一點!
筆者將 IcoMoon 跟修改後的 SVG 檔案放在網站上,可以自行打開原始碼比對。
- IcoMoon:http://muki.tw/blog-demo/svg-sprite/sprite-icomoon.svg
- MUKI edit:http://muki.tw/blog-demo/svg-sprite/sprite.svg
