Web前端開發最佳實踐(7):使用合理的技術方案來構建小圖標


大家都對網站上使用的小圖標肯定都不陌生,這些小圖標作為網站內容的點綴,增加了網站的美觀度,提高了用戶體驗,可是你有沒有看過在這些網站中使用的圖標都是用什么技術實現的?雖然大部分網站還是使用普通的圖片實現,不過可供使用的技術方案還不少,這些都歸功於新的Web技術的應用。

常見的小圖標應用方案

1. 最簡單的還是圖片,圖片

這個方案是使用最廣的方案,簡單有效。jQuery UI使用的就是這樣的方案。jQuery UI是把所有需要用到的小圖標放置在一張大的sprite圖片中,類似如下的圖片:

jQuery UI 圖標示例

用法也很簡單。應用圖標時,通過設置背景圖來展示不同的圖標。比如,要添加一個郵件的圖標,則需要設置classui-icon ui-icon-mail-closedui-iconui-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盡管使用廣泛,但是中文字體上的應用還很少,這主要是因為中文對應的字體文件過於龐大(中文博大精深~)。目前使用最多的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 偽對象在元素中插入內容,然后渲染內容為圖標。比如fafa-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提供了eotttf woffsvg這四種格式的字體文件。網站中往往只需要少數幾個圖標,但是需要引入所有的圖標文件,增加了額外的開銷。

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的示例:

Imgur

瀏覽器渲染后的效果如下圖:

Imgur

可以看到,在SVG中使用use可以引入在一個SVG圖片中的不同圖標。這樣的效果類似於CSS中的雪碧圖。

4. 純CSS生成圖標

隨着CSS的不斷發展,使用CSS不僅僅可以產生一些四四方方的線框效果,同時可以產生一些曲線和傾斜效果。主要利用了如下的CSS特性:border-radius、box-shadow、transform等效果及使用偽元素::before::after。這些效果的搭配使用,則可以產生一些特殊的形狀。這就給了我們一個單純使用CSS來生成一些簡單圖標的機會。如下圖是一個常見的RSS圖標:

Imgur

我們可以嘗試使用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生成圖標的庫。所有的圖標效果圖如下:

Imgur

結論

以上就是我們在網頁中常見的圖標構建技術。在實際的使用中需要結合瀏覽器兼容來選擇合適的方案。以當前的瀏覽器發展狀況,個人推薦使用Web Font 和 SVG的方案,這樣的方案更能適合當前高清屏幕的顯示。推薦使用icomoon.io庫,icomoon提供了Web Font和SVG兩種用於構建圖標的方案,也提供了PNG圖片用於降級處理。icomoon容許用戶選擇需要的圖標來打包,而不像BootStrap和FontAwsome提供了整個圖標文件,這樣保證了文件足夠小。此外在icomoon中,用戶也可以上傳自定義的圖標。可以看到icomoon提供了極大的便利和良好的瀏覽器兼容性。純CSS的方案還不夠成熟,瀏覽器兼容性也不夠好,可構建的圖標有限,不建議在實際的項目中使用,但可以作為學習的資料。

附錄


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM