使用SVG symbols創建圖標系統

在實現Web項目的圖標系統時,SVG是一個不錯的選擇。雖然使用SVG建立圖標系統有多種方式。在這篇文章中,咱們只看其中一種:SVG symbols。這項技術基於兩個元素的使用:<symbol><use>css

<symbol>元素用來對元素進行分組;它不會被直接顯示,大概至關於定義一個模板,而後使用<use>元素引用並進行渲染。html

咱們使用Illustrator建立並導出SVG圖標:git

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="24px" height="24px" viewBox="0 0 24 24"> <path fill="#E86C60" d="M17,0c-1.9,0-3.7,0.8-5,2.1C10.7,0.8,8.9,0,7,0C3.1,0,0,3.1,0,7c0,6.4,10.9,15.4,11.4,15.8 c0.2,0.2,0.4,0.2,0.6,0.2s0.4-0.1,0.6-0.2C13.1,22.4,24,13.4,24,7C24,3.1,20.9,0,17,0z"></path> </svg> 

而後將內容包裹在<symbol>元素中:github

<svg> <symbol viewBox="0 0 24 24" id="heart"> <path fill="#E86C60" d="M17,0c-1.9,0-3.7,0.8-5,2.1C10.7,0.8,8.9,0,7,0C3.1,0,0,3.1,0,7c0,6.4,10.9,15.4,11.4,15.8 c0.2,0.2,0.4,0.2,0.6,0.2s0.4-0.1,0.6-0.2C13.1,22.4,24,13.4,24,7C24,3.1,20.9,0,17,0z"></path> </symbol> </svg> 

如今若是咱們把這段代碼插入到咱們的頁面中,咱們會看到圖標並不顯示,由於要顯示圖標,咱們還須要使用<use>元素:瀏覽器

<body> <svg style="display: none;"> <symbol viewBox="0 0 24 24" id="heart"> <path fill="#E86C60" d="M17,0c-1.9,0-3.7,0.8-5,2.1C10.7,0.8,8.9,0,7,0C3.1,0,0,3.1,0,7c0,6.4,10.9,15.4,11.4,15.8 c0.2,0.2,0.4,0.2,0.6,0.2s0.4-0.1,0.6-0.2C13.1,22.4,24,13.4,24,7C24,3.1,20.9,0,17,0z"></path> </symbol> </svg> <svg> <use xlink:href="#heart"/> <!-- this is our visible icon --> </svg> </body> 

結果以下:緩存

SVG

換句話說,就是你定義了一組圖形對象(使用<symbol>元素)以後,可使用<use>元素來對它進行無限次實例化展現。你使用xlink:href屬性來指定你想要展現哪一組圖標,這裏,咱們要展現的是id#heart<symbol>元素。app

你可能注意到了咱們給包裹<symbol>元素的SVG標籤加了一個style="display: none;"的樣式:這是由於即便<symbol>自己沒有顯示,可是包裹它的<svg>元素依舊會渲染並佔用一些頁面空間,這就是爲何咱們須要隱藏svg元素。svg

如今咱們知道了<symbol><use>元素分別是什麼,以及它們是如何工做的,咱們能夠來創建咱們的SVG sprite了。工具

首先,你須要準備好全部圖標,每一個圖標放一個單獨的.svg文件。而後再建立一個新的(空白的).svg文件(我把它命名爲myicons.svg)。網站

在這個新的svg文件中,插入一個<svg>標籤,而後,對於每個你要放進去的圖標,分別用一個<symbol>元素來包裹。

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <symbol viewBox="0 0 24 24" id="heart"> <path fill="#E86C60" d="M17,0c-1.9,0-3.7,0.8-5,2.1C10.7,0.8,8.9,0,7,0C3.1,0,0,3.1,0,7c0,6.4,10.9,15.4,11.4,15.8 c0.2,0.2,0.4,0.2,0.6,0.2s0.4-0.1,0.6-0.2C13.1,22.4,24,13.4,24,7C24,3.1,20.9,0,17,0z"></path> </symbol> <symbol viewBox="0 0 32 32" id="arrow"> <path fill="#0f0f0f" d="M16,0C7.2,0,0,7.2,0,16s7.2,16,16,16s16-7.2,16-16S24.8,0,16,0z M22.8,13.6l-6,8C16.6,21.9,16.3,22,16,22 s-0.6-0.1-0.8-0.4l-6-8c-0.2-0.3-0.3-0.7-0.1-1S9.6,12,10,12h12c0.4,0,0.7,0.2,0.9,0.6S23,13.3,22.8,13.6z"></path> </symbol> </svg> 

每一個<symbol>元素都設置一個id,這個id用來在後面使用<use>的時候引用。

咱們還給每一個<symbol>元素指定了一個viewBox屬性。這個viewBox屬性定義了圖標的寬高比;它包含4個值,前面2個值一般爲0(但它實際上是依賴於圖標是如何繪製的),另外兩個值分別是SVG的寬和高(若是你對於viewBox屬性不熟悉,能夠看看這篇關於SVG縮放的文章)。

這樣你的圖標不須要保持相同的寬高比,由於你能夠給每一個圖標分別定義不一樣的viewBox屬性。

最後一步,咱們能夠給每一個圖標添加一個<title>標籤,提高它的可訪問性。

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <symbol viewBox="0 0 24 24" id="heart"> <title>Heart</title> <path fill="#E86C60" d="M17,0c-1.9,0-3.7,0.8-5,2.1C10.7,0.8,8.9,0,7,0C3.1,0,0,3.1,0,7c0,6.4,10.9,15.4,11.4,15.8 c0.2,0.2,0.4,0.2,0.6,0.2s0.4-0.1,0.6-0.2C13.1,22.4,24,13.4,24,7C24,3.1,20.9,0,17,0z"></path> </symbol> <symbol viewBox="0 0 32 32" id="arrow"> <title>Arrow</title> <path fill="#0f0f0f" d="M16,0C7.2,0,0,7.2,0,16s7.2,16,16,16s16-7.2,16-16S24.8,0,16,0z M22.8,13.6l-6,8C16.6,21.9,16.3,22,16,22 s-0.6-0.1-0.8-0.4l-6-8c-0.2-0.3-0.3-0.7-0.1-1S9.6,12,10,12h12c0.4,0,0.7,0.2,0.9,0.6S23,13.3,22.8,13.6z"></path> </symbol> </svg> 

咱們的SVG sprite如今能夠投入使用了。你能夠保存文件爲myicons.svg,放在資源文件夾中(我一般把這個文件夾明明爲img)。

接下來展現咱們的圖標,你須要作的就是在文檔中你想要放置圖標的位置插入下面這一小段:

<svg> <use xlink:href="img/myicons.svg#heart"/> </svg> 

就這樣,so easy!

瀏覽器兼容性如何呢?在IE中經過<use>引用外部SVG文件的方法是不可行的,IE9以上也不行(不過,這個問題在Edge中已經解決了)。

那要如何解決呢?咱們來看看兩種可能的解決方案。

咱們能夠在文檔的頂部引入SVG sprite,而後使用<use>標籤引用圖標:

<svg style="display: none;"> <!-- this is our svg sprite --> <symbol viewBox="0 0 24 24" id="heart"> <path fill="#E86C60" d="M17,0c-1.9,0-3.7,0.8-5,2.1C10.7,0.8,8.9,0,7,0C3.1,0,0,3.1,0,7c0,6.4,10.9,15.4,11.4,15.8 c0.2,0.2,0.4,0.2,0.6,0.2s0.4-0.1,0.6-0.2C13.1,22.4,24,13.4,24,7C24,3.1,20.9,0,17,0z"></path> </symbol> <symbol viewBox="0 0 32 32" id="arrow"> <!-- ... --> </symbol> </svg> <svg> <use xlink:href="#heart"/> <!-- this is our visible icon --> </svg> 

注意xlink:href屬性和id標識符是惟一對應的(它不能引用外部資源中的id)。

這種方法很是好用,但缺點是SVG sprite不能緩存。

咱們可使用一個polyfill;舉個例子,svgxuse。這個polyfill能夠根據<use>元素的引用,獲取外部SVG資源中的id,而瀏覽器自己並不能這樣作。基本遠離就是,這個polyfill遍歷文檔中的<use>元素,而後若是它引用的是瀏覽器沒法加載的外部SVG文件,它就在外部SVG中抓取並預置到文檔中的<body>中。good!

你能夠在Github repo中下載這個polyfill,在文檔中引入,就ok了。

注意:SVG只在IE9以上支持;因此若是你須要支持IE8及如下的瀏覽器,你須要另外再寫一套降級(例如,使用png圖片方案)。

接下來,怎麼給SVG添加樣式呢?給SVG <use>元素添加樣式須要一點技巧。這是由於SVG 圖標引用這種方式有本身單獨的DOM結構(也就是shadow DOM),CSS選擇器並不能獲取到,因此假設咱們有以下的圖標:

<svg class="icon"> <use xlink:href="img/myicons.svg#heart"/> </svg> 

而後這樣添加樣式:

.icon path { fill: #000000; }

是沒有辦法工做的。

如何解決這個問題呢?好比說你想要改變圖標的填充顏色。首先,確保fill屬性不是svg文件中內聯定義的。因此,若是圖標 sprite以下:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <symbol viewBox="0 0 24 24" id="heart"> <title>Heart</title> <path fill="#E86C60" d="M17,0c-1.9,0-3.7,0.8-5,2.1C10.7,0.8,8.9,0,7,0C3.1,0,0,3.1,0,7c0,6.4,10.9,15.4,11.4,15.8 c0.2,0.2,0.4,0.2,0.6,0.2s0.4-0.1,0.6-0.2C13.1,22.4,24,13.4,24,7C24,3.1,20.9,0,17,0z"></path> </symbol> <symbol viewBox="0 0 32 32" id="arrow"> <title>Arrow</title> <path fill="#0f0f0f" d="M16,0C7.2,0,0,7.2,0,16s7.2,16,16,16s16-7.2,16-16S24.8,0,16,0z M22.8,13.6l-6,8C16.6,21.9,16.3,22,16,22 s-0.6-0.1-0.8-0.4l-6-8c-0.2-0.3-0.3-0.7-0.1-1S9.6,12,10,12h12c0.4,0,0.7,0.2,0.9,0.6S23,13.3,22.8,13.6z"></path> </symbol> </svg> 

把內聯fill屬性刪除,以下:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <symbol viewBox="0 0 24 24" id="heart"> <title>Heart</title> <path d="M17,0c-1.9,0-3.7,0.8-5,2.1C10.7,0.8,8.9,0,7,0C3.1,0,0,3.1,0,7c0,6.4,10.9,15.4,11.4,15.8 c0.2,0.2,0.4,0.2,0.6,0.2s0.4-0.1,0.6-0.2C13.1,22.4,24,13.4,24,7C24,3.1,20.9,0,17,0z"></path> </symbol> <symbol viewBox="0 0 32 32" id="arrow"> <title>Arrow</title> <path d="M16,0C7.2,0,0,7.2,0,16s7.2,16,16,16s16-7.2,16-16S24.8,0,16,0z M22.8,13.6l-6,8C16.6,21.9,16.3,22,16,22 s-0.6-0.1-0.8-0.4l-6-8c-0.2-0.3-0.3-0.7-0.1-1S9.6,12,10,12h12c0.4,0,0.7,0.2,0.9,0.6S23,13.3,22.8,13.6z"></path> </symbol> </svg> 

而後在你的css代碼中,加入:

.icon { fill: #00000; /* this will be your icons default color */ }

由於你沒有在SVG中給path元素指定fill,因此它們會繼承父級元素,即SVG的fill屬性,這樣你能夠直接使用CSS選擇器修改這個屬性。

如今,若是咱們只想改變一個圖標的fill,怎麼辦呢?咱們給這個圖標再單獨指定一個class便可:

<svg class="icon my-class-name"> <use xlink:href="img/myicons.svg#heart"></use> <svg> 

而後使用CSS改變它的fill值:

.my-class-name { fill: red; }

使用Nucleo建立SVG symbol sprite

手動建立一個SVG symbol sprite是很是麻煩的,特別是若是你有相對多的圖標。Nucleo自動化SVG symbol sprites構建工具能夠幫助你省下不少瑣碎活。

從Nucleo的網站上,選擇你想要下載圖標,而後點擊下載按鈕。在彈出的設置窗口中,勾上‘Export as <symbol>選項,而後填寫你的資源文件夾的路徑(這裏會爲<use>元素設置一個xlink:href值);填寫一個文件名(這是你的SVG sprite文件的名字)。而後點擊保存。完成啦!你的sprite就能夠用了。

SVG

你下載的文件夾中會包含幾樣東西:

  • 你的SVG sprite;
  • 一個style.css文件(在css文件夾中):它包含基本的SVG樣式(例如,你在app中設置的fill/stroke屬性);你須要複製這塊內容到你的樣式文件中(或者做爲一個額外的css文件引入);
  • 一個svgxuse.min.js文件(在js文件夾中),這是針對IE9+的polyfill;你須要在你的文檔中引入這個文件,若是你但願圖標在IE9+的瀏覽器中能夠正確顯示的話;
  • 最後,一個demo.html文件。

基本上,這個demo文件列出了全部你下載的圖標,你能夠直接在你的文檔中引入它們:點擊你想要引入的圖標,它就會選中你須要複製的代碼片斷,而後在你的文檔中粘貼便可。

SVG

圖標也會按照你在Nucleo app中設置的樣式顯示。

怎麼給單個圖標添加樣式呢?你能夠給圖標指定一個class

<svg class="nc-icon grid-32 glyph my-class-name"> <use xlink:href="img/myicons.svg#double-left"/> </svg> 

而後在CSS中修改:

.my-class-name { color: purple; }

OK。可是,Nucleo圖標是雙色的....若是我想改變的是其中的第二種顏色的?這也好辦,加上:

.my-class-name use { color: orange; }

OK啦。

咱們的symbols有一些額外的技巧。

  • 咱們的內聯圖標有可定製的stroke。若是你想要改變某個圖標的stroke-width屬性呢?假設你下載的圖標stroke-width2px,那麼stroke-2類會自動添加到SVG元素上。若是你想要把stroke切換爲3px,只須要把stroke-2類改成stroke-3類就能夠啦。
  • 那如何讓圖標和文本對齊呢?在demo文件中,在頂部,能夠選擇‘align to text’;而後複製SVG片斷並粘貼到你的文檔中(感謝Cloud Four提供的'align to text'樣式)。 注意,在這裏,SVG會繼承文本的顏色;可是,你一樣可使用一個自定義類,給它添加自定義樣式,和前面同樣。
  • 若是你更傾向於在文檔中引入SVG sprite(而不是做爲一個外部的SVG文件引用),不要勾選'Reference external SVG'選項(在demo文件的頂部);這會自動將xlink;href屬性設置爲和<symbol>的惟一標識符id相等的名字。

使用SVG symbols真的是管理圖標的很是智能的方法;這是爲何咱們在Nucleo中加入了'symbol export'功能。

使用Nucleo管理圖標也是很是方便的,即便你手頭有多個項目:你須要作的只是建立一個項目,添加你須要的圖標,而後點擊幾下,下載便可。

本文根據@Claudia Romano的《How to create an icon system using SVG symbols》所譯,整個譯文帶有咱們本身的理解與思想,若是譯得很差或有不對之處還請同行朋友指點。如需轉載此譯文,需註明英文出處:https://nucleoapp.com/how-to-create-an-icon-system-using-svg-symbols/

著做權歸做者全部。
商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
原文: http://www.w3cplus.com/svg/how-to-create-an-icon-system-using-svg-symbols.html © w3cplus.com

相關文章
相關標籤/搜索