大家都對網站上使用的小圖標肯定都不陌生,這些小圖標作為網站內容的點綴,增加了網站的美觀度,提高了用戶體驗,可是你有沒有看過在這些網站中使用的圖標都是用什么技術實現的?雖然大部分網站還是使用普通的圖片實現,不過可供使用的技術方案還不少,這些都歸功於新的Web技術的應用。
常見的小圖標應用方案
1. 最簡單的還是圖片,圖片
這個方案是使用最廣的方案,簡單有效。jQuery UI使用的就是這樣的方案。jQuery UI是把所有需要用到的小圖標放置在一張大的sprite圖片中,類似如下的圖片:
用法也很簡單。應用圖標時,通過設置背景圖來展示不同的圖標。比如,要添加一個郵件的圖標,則需要設置class
為ui-icon ui-icon-mail-closed
。ui-icon
和 ui-icon-mail-closed
的定義如下:
.ui-icon {
background-image: url("/themeroller/images/ui-icons_888888_256x240.png");
}
.ui-icon-mail-closed {
background-position: -80px -96px;
}
可以看到jQuery UI的方案還是傳統的通過設置不同的background-position
來切換不同的圖標的。此種方法簡單,但是不同的皮膚需要有不同的顏色的圖片來對應,光jQuery UI默認內置的圖片就有很多種。
使用圖片的缺點也明顯,最大的缺點是不好自定義圖標的大小和顏色。限制了頁面的設計。
2. 使用Web Fonts
通過Web Font技術來構建小圖標是目前使用最廣泛的代替普通圖片的方案。Web Font是在CSS3中引入的技術,w3c官方網站上的地址是:css3-webfonts。如下是使用Web Font的示例:
@font-face {
font-family: Delicious;
src: url('Delicious-Roman.otf');
}
@font-face {
font-family: Delicious;
font-weight: bold;
src: url('Delicious-Bold.otf');
}
h3 {
font-family: Delicious, sans-serif;
}
Web Font目前已經得到了所有主流瀏覽器的支持,所以在網頁中已經大量的使用。caniuse網站上查到的Web Font的瀏覽器支持狀況如下:
Web Font的使用使得網站不再是局限於系統內置的字體,網站中字體的顯示也更具有個性。Web Font盡管使用廣泛,但是中文字體上的應用還很少,這主要是因為中文對應的字體文件過於龐大(中文博大精深~)。目前使用最多的Web Font是由Google提供的服務,這里有一篇文章介紹Google Web Font的使用。這里就不在詳細展開。今天重點要說的是Web Font用於構建小圖標。
由於Web Font可以自定義字體,那么就給了設計者設計一種特殊字體的可能,即圖標字體。這種字體具有文字的特性,比如可以設置字體的顏色和大小,但同時具有圖標的外觀。目前使用很廣泛的Web Font圖標庫是font awesome 和 BootStrap框架包含的圖標模塊glyph icons。Font Awesome提供了多達519個圖標,BootStrap中也提供了260個圖標。這些圖標基本上涵蓋了網頁中常用的圖標。如果不知道如何選擇圖標,這個網站可以輔助查找。如下示例使用Font Awesome 和 BootStrap展示郵件圖標:
<!—使用Font Awesome 生成圖標-->
<i class="fa fa-envelope-o"></i>
<!—使用BootStrap 生成圖標-->
<i class="glyphicon glyphicon-envelope"></i>
這類框架生成圖標的原理類似,利用 ::before
和 ::after
偽對象在元素中插入內容,然后渲染內容為圖標。比如fa
和 fa-envelope-o
的定義如下:
.fa {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
transform: translate(0, 0);
}
.fa-envelope-o:before {
content: "\f003";
}
fa
類定義了元素的字體,即Web Font字體, fa-envelope-o
的作用是在元素中插入內容文字"\f003"
,內容文字通過定義的Web Font字體渲染為一個郵件圖標。
這種方案的優勢明顯,通過CSS就可以很方便地控制圖標的大小和顏色,在開發中帶來了極大的便利性。使用Web Font生成的圖標,會自動適用不同的設備分辨率,不會因為放大和縮小而影響圖標顯示的質量。這個看似很完美的方案,但是在使用過程中還是有一些缺點的。最大的缺點是瀏覽器的支持上不夠完美,瀏覽器把圖標作為文字進行渲染,由於抗鋸齒的優化不好,使得圖標看起來不夠銳利。其次,由於瀏覽器兼容性的問題,需要提供至少四種不同類型的字體文件。比如BootStrap提供了eot
、 ttf
、 woff
、svg
這四種格式的字體文件。網站中往往只需要少數幾個圖標,但是需要引入所有的圖標文件,增加了額外的開銷。
3. 使用SVG
SVG是一種基於XML的圖形格式。這是一種可縮放的矢量圖形。SVG是由W3C制定的標准,在2003年成為了W3C的推薦標准。相比較其他的圖像格式,SVG的優勢在於:SVG可以被很多工具讀取和修改、SVG的尺寸更小、SVG圖像在任何的分辨率下都可以高質量地打印。
SVG主要有如下的使用方式:
img標簽直接引用
這種方式簡單,直接把SVG格式圖片看作為普通的圖片來引用。這種方式在實際的使用場景中應用不多。
內聯方式
IE9、Firefox、Opera、Chrome及Safari都支持內聯的SVG。IE8及以下版本瀏覽器可以通過安裝插件來支持SVG。內聯的SVG直接作為HTML文檔的一部分,不需要單獨請求。內聯的SVG使用上很不方便,如果在HTML中加入大段的SVG代碼,則很難維護,代碼也無法復用。
Data URIs
這種方式是把SVG文件直接轉成base64編碼格式,然后以Data URIs的方式引用。示例代碼如下:
.icon{
background: url(data:text/svg+xml;base64,<base64 encoded data>)
}
使用SVG中的<symbol>
元素
在SVG的規范中,可以通過<symbol>
元素來組合多個圖片到一個SVG文件中。在SVG中每個<symbol>
代表着一個獨立的圖片或者圖標。代碼示例如下:
<svg display="none" width="0" height="0" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="icon-home" viewBox="0 0 1024 1024">
<title>home</title>
<path class="path1" d="M1024 590.444l-512-397.426-512 397.428v-162.038l512-397.426 512 397.428zM896 576v384h-256v-256h-256v256h-256v-384l384-288z"></path>
</symbol>
<symbol id="icon-home2" viewBox="0 0 1024 1024">
<title>home2</title>
<path class="path1" d="M512 32l-512 512 96 96 96-96v416h256v-192h128v192h256v-416l96 96 96-96-512-512zM512 448c-35.346 0-64-28.654-64-64s28.654-64 64-64c35.346 0 64 28.654 64 64s-28.654 64-64 64z"></path>
</symbol>
</defs>
</svg>
如上代碼示例來自於 icomoon.io。可以看到SVG元素中包含了兩個symbol元素,每個元素都有一個id屬性。這兩個元素實際上是兩個圖標。使用的方法是通過在SVG中使用use引入具體某個symbol對應的id值,即引入了symbol元素對應的圖標。如下是在HTML代碼中引入symbol的示例:
瀏覽器渲染后的效果如下圖:
可以看到,在SVG中使用use可以引入在一個SVG圖片中的不同圖標。這樣的效果類似於CSS中的雪碧圖。
4. 純CSS生成圖標
隨着CSS的不斷發展,使用CSS不僅僅可以產生一些四四方方的線框效果,同時可以產生一些曲線和傾斜效果。主要利用了如下的CSS特性:border-radius、box-shadow、transform等效果及使用偽元素::before
和 ::after
。這些效果的搭配使用,則可以產生一些特殊的形狀。這就給了我們一個單純使用CSS來生成一些簡單圖標的機會。如下圖是一個常見的RSS圖標:
我們可以嘗試使用CSS來生成這樣的效果,假設此圖標對應的HTML只有一個簡單的元素
<i class="icon-rss"></i>
接下來定義這個icon-rss
類,先定義基本的高和寬:
.icon-rss {
width: 22px;
height: 22px;
overflow: hidden;
margin: 6px;
position: relative;
}
接下來利用::before偽對象定義圖標左下角的實心圓:
.icon-rss:before {
content: '';
width: 6px;
height: 6px;
box-shadow: 0 0 32px inset;
left: 0;
bottom: 0;
position: absolute;
border-radius: 50%;
}
如上的代碼中,設置元素為絕對定位並定位於左下角。使用border-radius構建一個圓形,然后應用box-shadow,設置圓形內陰影。達到實心圓的效果。
構建完實心圓后,接下來構建右上角的兩個半圓弧。這次使用::after
偽元素。
.icon-rss:after {
content: '';
width: 27px;
height: 27px;
right: 15%;
top: 15%;
position: absolute;
border-radius: 50%;
border: 4px solid transparent;
box-shadow: inset 0 0 0 2px,0 0 0 2px;
}
代碼中同樣設置元素為絕對定位,並定位於右上角。使用border-radius構建一個圓形,但因為設置了元素的高度和寬度遠大於外框的高寬,所以超出部分被外框遮擋,達到了1/4圓弧的效果。但僅僅設置這些並不能產生兩條圓弧的效果,所以代碼中借助了box-shadow
,產生了內外兩個陰影,實際顯示成為兩條圓弧。兩條圓弧的距離太近,通過設置一個透明的border
,加大了兩條陰影的距離。
至此,一個RSS圖標產生。看起來很繁瑣,構建這樣一個圖標需要有很好的CSS功底。好在有第三方庫可以使用。icono就是這樣一個純CSS生成圖標的庫。所有的圖標效果圖如下:
結論
以上就是我們在網頁中常見的圖標構建技術。在實際的使用中需要結合瀏覽器兼容來選擇合適的方案。以當前的瀏覽器發展狀況,個人推薦使用Web Font 和 SVG的方案,這樣的方案更能適合當前高清屏幕的顯示。推薦使用icomoon.io庫,icomoon提供了Web Font和SVG兩種用於構建圖標的方案,也提供了PNG圖片用於降級處理。icomoon容許用戶選擇需要的圖標來打包,而不像BootStrap和FontAwsome提供了整個圖標文件,這樣保證了文件足夠小。此外在icomoon中,用戶也可以上傳自定義的圖標。可以看到icomoon提供了極大的便利和良好的瀏覽器兼容性。純CSS的方案還不夠成熟,瀏覽器兼容性也不夠好,可構建的圖標有限,不建議在實際的項目中使用,但可以作為學習的資料。