SVG

SVG

最近網站的 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 檔案後我的處理過程:

  1. 用 Adobe Illustrator 先開來整理一下,修改圖層名稱、刪去合併不必要的圖層
  2. 輸出成 SVG 和 1x 解析度的 PNG
  3. SVG 檔用svgo最佳化、PNG 會用pngquantzopflipng處理過

使用方式則還是當成一般外部圖片為主,需要動畫效果才會用 inline SVG。


更之前的文章