應該瞭解的 Web 圖標解決方案


A picture is worth a thousand words, 一圖勝千言。 沒錯,從 Web 誕生的那天開始,圖標就成爲視覺層面不可或缺的一個元素,在一個 Web 頁面中,一個圖標不只僅能從視覺上帶來優雅感,更重要的是,它對此處的功能起到了點睛之筆的做用,它會使得用戶更容易理解你的產品。那麼,在咱們當下的 Web 前端開發中,最多見的圖標解決方案有哪些呢?大概是三種,圖片、IconFont 和 Svg。圖片就不說了,就是整一坨小的 png 圖片做爲圖標,最終把他們合在一個圖片裏,此種技術還有一個好聽的名字 CSS Sprites,國人稱爲 雪碧圖,此種方案仍是 Web 前端性能優化軍規之一,下降 http 請求數來達到提速的目的。javascript

圖片我們今天不說了,沒啥意思。我們今天聊聊 IconFont 和 inline SVG,而後把這兩個方案的優劣進行一個對比,而後再介紹介紹常見的 IconFont 庫及 inline SVG 的庫,最後再展現一個小 Demo 給你們看一看具體在頁面上 IconFont 和 Svg 有什麼不一樣。css

IconFont 介紹

IconFont 使用的技術是 CSS 自定義字體,用戶能夠把圖標集合打包成字體文件 ( 如何打包,可以使用 iconfont.cn ),而後經過 @font-face 來自定義一個字體,最後經過設置 font-family 以及經過使用圖標字體的 unicode編碼 來使用圖標。html

在 CSS 裏聲明字體,編寫 unicode 編碼對應的圖標:前端

@font-face {
  font-family: 'FontAwesome';
  src: url('../fonts/fontawesome-webfont.eot?v=4.6.3');
  src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.6.3') format('embedded-opentype'),         
        url('../fonts/fontawesome-webfont.woff2?v=4.6.3') format('woff2'), 
        url('../fonts/fontawesome-webfont.woff?v=4.6.3') format('woff'), 
        url('../fonts/fontawesome-webfont.ttf?v=4.6.3') format('truetype'), 
        url('../fonts/fontawesome-webfont.svg?v=4.6.3#fontawesomeregular') format('svg');
  font-weight: normal;
  font-style: normal;
}

.fa {
 font-family: 'FontAwesome';
 display: inline-block;
}

.fa-icon:after {
  content: '\f00c'
}

在 HTML 裏這麼寫就能夠了:java

<i class="fa-icon"></i>

IconFont 有大量的開源解決方案,並且有不少現成的圖標,比較具備表明性的以下:git

  • FontAwesome,具有完善大量的圖標庫,對於定製化程度不高的項目,能夠直接拿過來用github

  • Iconfont.cn,阿里的解決方案,不但有現成的圖標供你選擇,還能夠上傳本身的圖標來製做 IconFontweb

IconFont 的最大的好處就是瀏覽器兼容性好(IE6+),能夠經過 CSS 來控制圖標大小、顏色。chrome

inline SVG 介紹

使用 IconFont 是把已有的矢量文件(一般是不少 .svg 文件)打包成字體文件,而 inline SVG 則是把 .svg 文件合併成一個大的 .svg 文件,而後在 HTML 中引用這個文件便可,具體步驟參考下面。gulp

合併 svg

在這裏搞了三個 svg 文件,準備把他們合併在一塊兒:

<img style="display:block;width:100%;float:none;" src="http://ww4.sinaimg.cn/large/8df27f17gw1f4b11i2l79j20xe0i0acj.jpg"/>

SVG Symbol

我這裏使用的是 svg-symbol 方案來合併 svg。

還有一個合併方法是 SVG defs,這個比 SVG Symbol 要雞肋不少,在此就不介紹了。

經過使用 gulp-svg-symbols 來把 svg 文件合併:

var gulp       = require('gulp');
var svgSymbols = require('gulp-svg-symbols');

gulp.task('sprites', function () {
  return gulp.src('assets/svg/*.svg')
    .pipe(svgSymbols())
    .pipe(gulp.dest('assets'));
});

最終獲得的 svg 文件:

<svg xmlns="http://www.w3.org/2000/svg" style="width:0; height:0; visibility:hidden;">
    <symbol id="circle" viewBox="0 0 200 200">
      <g class="transform-group">
        <g transform="scale(0.1953125, 0.1953125)">
          <path d="..." fill="#272636"/>
        </g>
      </g>
    </symbol>
    <symbol id="password" viewBox="0 0 200 200">
      <g class="transform-group">
        <g transform="scale(0.1953125, 0.1953125)">
          <path d="..." fill="#272636"/>
        </g>
      </g>
    </symbol>
    <symbol id="profile" viewBox="0 0 200 200">
      <g class="transform-group">
        <g transform="scale(0.1953125, 0.1953125)">
          <path d="..." fill="#272636"/>
        </g>
      </g>
    </symbol>
</svg>

使用方法

在 HTML 文件中聲明 svg,而後經過 <svg><use xlink:href="#id" /></svg> 來使用:

<svg xmlns="http://www.w3.org/2000/svg" style="width:0; height:0; visibility:hidden;">
    <symbol id="circle" viewBox="0 0 200 200">
      <g class="transform-group">
        <g transform="scale(0.1953125, 0.1953125)">
          <path d="..." fill="#272636"/>
        </g>
      </g>
    </symbol>
    <symbol id="password" viewBox="0 0 200 200">
      <g class="transform-group">
        <g transform="scale(0.1953125, 0.1953125)">
          <path d="..." fill="#272636"/>
        </g>
      </g>
    </symbol>
    <symbol id="profile" viewBox="0 0 200 200">
      <g class="transform-group">
        <g transform="scale(0.1953125, 0.1953125)">
          <path d="..." fill="#272636"/>
        </g>
      </g>
    </symbol>
</svg>

<svg class="icon"><use xlink:href="#profile" /></svg>
<svg class="icon"><use xlink:href="#password" /></svg>
<svg class="icon"><use xlink:href="#circle" /></svg>

你也能夠經過 <svg><use xlink:href="http://cdn.com/assets/symbols.svg#id" /></svg> 來直接使用存儲在 CDN 上的 svg 文件,若是感受每一個都要寫 CDN 的地址太麻煩,則能夠封裝 JS 工具,統一維護,統一管理。

inline SVG 目前沒有什麼特別推薦的開源解決方案,通常狀況下,圖標都是本身的,本身經過工具打包就已經很方便了,並且很難經過純 CSS 或 JS 來解決,由於它跟 HTML 的關聯性太大了,即便是這樣,仍是推薦一個庫給你們瞭解瞭解:

SVGInjector

IconFont 與 inline SVG 方案對比

瀏覽器兼容性

IconFont inline SVG
IE6+ IE9+ , Android 3.0+ 移動端支持很好,如今可使用

尺寸、顏色是否容易控制

IconFont inline SVG
瀏覽器會認爲它是一個字體,所以只能使用 color 和 font-size 控制,並且尺寸特別不精細 支持多色、局部顏色控制、控制尺寸使用 width 和 height

訪問的穩定性

IconFont inline SVG
Font 在 CDN 上會有跨域問題;並且字體下載不下來是很常見的事;還有一些已知的Chrome的Bug ;貌似代理性質的瀏覽器,像 UC ,就不支持自定義 Font;一些瀏覽器攔截插件會攔截自定義字體...... Svg很正常

語義化

IconFont inline SVG
根本不語義化,你要寫多餘沒有意義的標籤,對 SEO 很不利 Svg 是圖形,人家就是圖形,並且 SVG Symbol 支持 title 和 description 屬性,很是友好

用起來是否順滑

IconFont inline SVG
本身生成 svg 而後使用工具打包成多個字體文件,而後用 unicode 對應使用 SVG Symbol 使用打包工具生成 SVG 集合,直接經過 ID 使用

IconFont 與 SVG 的 Demo

請去個人CodePen

總結

若是,你的產品須要支持 IE8 及如下,仍是推薦使用 IconFont ,由於使用 SVG Symbol 的話,你須要考慮在低端瀏覽器下的兼容性,常見的作法是,生成一些 png 的圖片作 fallback,而後在低端瀏覽器下顯示,把 svg 隱藏.....

若是,你只須要考慮 IE9+ 和 Android 3.0 + ,毫無疑問,inline SVG 是惟一選擇!

相關文章
相關標籤/搜索