最近網站的 icon 都盡量改用 SVG 向量檔了,網路上也有不少資源,像是 Material Icons,累積了一些心得可以記錄一下,其實早在 GitHub 開使用 icon font 之前,大部分的瀏覽器就都有支援 SVG 了,只不過當時的支援還不夠完備,會各自有一些問題,這應該也是 Github 當年不先用 SVG,而是用 icon font 先檔了幾年的主因,總之現在比較不用擔心這些問題了,所以 GitHub 又開槍轉用 SVG icon 了。
GitHub 的用法是 inline SVG 為主,我自己則是用<picture>
比較多:
<picture>
<source srcset="/path/to/icon.svg" type="image/svg+xml">
<img src="/path/to/icon.png" alt="" width="32" height="32" />
</picture>
CSS Trick 有一篇文章 A Complete Guide to SVG Fallbacks 則介紹了各種在網頁內放入 SVG 圖檔的古老方法,用<picture>
是比較新的,沒列在其中,而我是為了向下相容選擇用<picture>
,因為支援<picture>
標籤的瀏覽器都很新了,對於 SVG 的支援度很夠,剩下少數(大概都是 IE)就讓他直接吃 png 之類的(PS: pngquant 處理過的 PNG 很多可以直接在 IE6 上顯示透明色),這樣用起來就像是一般<img>
一樣,SVG 檔可以先用 svgo 工具處理過,除此之外,我通常會先用 Adobe Illustrator 把不必要的圖層階層刪除,圖層在 SVG 原始碼裡面通常是會<g>
標籤,另外也記得要把圖層名稱(id)改成 ASCII only 的名稱,甚至直接編輯原始碼刪除 id,因為 svgo 不會處理這部分。
用外部 SVG 檔案好處是可以善用 browser cache 減少傳輸量,尤其是大量重複使用的圖片,不過也會犧牲一些 SVG 的特性,例如會因此不能直接用 CSS 來調整樣式,做 transition,做動畫等等,所以有時候也是會用 inline SVG,就可以搭配 CSS、JS 弄出很多不錯的效果(Safari 偶爾還有遇到無解 bug),不過要讓 inline SVG fallback 回一般圖片就比較麻煩些了,在做這件事之前可以先看一下是不是有需要支援,以前是 iOS 不支援,現在還有機會碰到的大概還是 IE(6-8)吧,總之,如果有需要的話,就是參考 CSS Trick 的 SVG Fallbacks 這篇文章,使用
<svg width="96" height="96">
<image xlink:href="svg.svg" src="svg.png" width="96" height="96" />
</svg>
這是個很有趣的技巧,首先<image>
標籤是合法的 SVG 元素,所以放在 SVG 不成問題,但是不支援 SVG 的瀏覽器,照理說也不應該認得<image>
標籤啊,其實,<image>
在很久以前就一直是<img>
的別名了,甚至在 WHATWG 的 parse HTML 文件的流程裡都還有提到處理的方式,而經過測試也都證實了以前的瀏覽器確實是這樣的行為,文裡也有各瀏覽器的行為和支援狀況,不支援 inline SVG 的就會顯示替代的 png 或 jpg 。
文章裡面還有提到背景圖使用 SVG 的處理方式,不過因為我沒這樣使用,所以沒什麼實做到,另外最近也有人用外部 SVG 加上 CSS filter 來改變 SVG icon 顏色,不過這太技巧太新了,考慮到支援度我也是沒有用過。
親和力問題的部分,一樣 CSS Tricks 有篇文章 Accessible SVG 在講相關的作法,像是用<title>
加替代文字,加上role="img"
等;如果要自己編寫 SVG,W3C 還有份 Authering Guide 可以參考,除了親和力相關的資訊外還有不少技巧可以參考。
最後整理一下,拿到 svg 檔案後我的處理過程:
- 用 Adobe Illustrator 先開來整理一下,修改圖層名稱、刪去合併不必要的圖層
- 輸出成 SVG 和 1x 解析度的 PNG
- SVG 檔用
svgo
最佳化、PNG 會用pngquant
和zopflipng
處理過
使用方式則還是當成一般外部圖片為主,需要動畫效果才會用 inline SVG。