該如何以正確的姿勢插入SVG Sprites?

蘇南發表於2018-09-21

大家好,這裡是@IT·平頭哥聯盟,我是首席填坑官——蘇南(South·Su),今天要給大家分享的是SVG sprite(也叫雪碧圖),所謂雪碧圖,當然就不是我們常喝的雪碧飲料(Sprites)哦,哈哈~

     當下流程的移動端,手機型號太多太多,今天工作專案中突然發現還有同事在使用以前大家 曾經包括現在還很熟悉的CSS 圖片精靈,被我們的測試MM找來說圖片在iphone6、iphone plus、iphone x等大屏的手機全糊了,當時我就懵逼了,我說怎麼會呢,後面一看,果然如此啊,看了下程式碼,原來是用的圖片,我說為什麼不用svg呢??然後同事說一個一個的圖示好麻煩,我說可以用svg sprite啊,~~>﹏<,這個時候輪到同事一臉懵逼了……,所以想著可能是不是同樣還有很多同學也不知道SVG symbols呢,那麼這就給大家分享一下:

      SVG英文全稱為( Scalable Vector Graphics),意思為可縮放的向量圖形。它是基於XML(Extensible Markup Language),由World Wide Web Consortium(W3C)聯盟進行開發的。嚴格來說應該是一種開放標準的向量圖形語言,可讓你設計激動人心的、高解析度的Web圖形頁面,SVG是一種採用XML 來描述二維圖形的語言,**那麼symbol元素是什麼呢?**單純翻譯的話,是“符號”的意思,然我的理解是symbol元素用來定義一個圖形模板物件,它可以用一個<use>元素例項化。symbol元素對圖形的作用是在同一文件中多次使用,新增結構和語義,SVG是無論如何放大縮小都不會糊,而圖片當展示的尺寸大於圖片本身,就會糊了,糊了,糊了……


clipboard.png

<div class="icon-sprite"></div>

.icon-sprite {//首席填坑官∙蘇南的專欄,梅斌的專欄
    width: 45px;
    height: 45px;
    background-image: url(https://github.com/meibin08/img/sprite_icon.png);
    background-size: 100px 350px;
    background-position: 0 -60px;//**重點在於它**
    background-repeat: no-repeat;
}
複製程式碼

      在以前我們為了效能優化,多圖示合在一張圖上面,然後再使用css的 background-position,來定位, 好處是減少了頁面的載入,要命的問題是定位遇到相容問題,1px\.5px偏差時,搞的你死去活來,後來移動端更是不清晰,被人罵了又罵。

âå®å®å¿éè¦âçå¾çæç´¢ç»æ

當後來有一天,我發現了它svg,當然僅僅svg就拿出來吹水,肯定是會被人噴的一臉口水的, SVG symbols/**SVG symbols**/SVG symbols **重要的事說三遍不過份吧**,這項技術基於兩個元素的使用:<symbol>和<use> 

從ps或者Illustrator建立並匯出SVG圖示,原始碼大概是這樣的:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1024 1024"> 
	<path style="fill-rule: evenodd;" d="M941.714 512q0 143.433-83.712 258.011t-216.283 158.574q-15.433 2.853-22.565-3.986t-7.131-17.152v-120.576q0-55.442-29.696-81.152 32.585-3.438 58.587-10.277t53.723-22.272 46.299-37.998 30.281-60.014 11.703-86.016q0-69.157-45.129-117.723 21.138-52.005-4.571-116.553-16.018-5.157-46.299 6.29t-52.553 25.161l-21.723 13.714q-53.138-14.848-109.714-14.848t-109.714 14.848q-9.143-6.29-24.283-15.433t-47.726-22.016-49.152-7.717q-25.161 64.585-3.986 116.553-45.129 48.567-45.129 117.723 0 48.567 11.703 85.723t29.989 60.014 46.007 38.29 53.723 22.272 58.587 10.277q-22.857 20.553-28.014 58.843-11.995 5.705-25.71 8.558t-32.585 2.853-37.413-12.288-31.707-35.73q-10.862-18.286-27.721-29.696t-28.27-13.714l-11.447-1.719q-11.995 0-16.567 2.56t-2.853 6.583 5.157 8.009 7.424 6.839l3.986 2.853q12.581 5.705 24.869 21.723t17.993 29.147l5.705 13.129q7.424 21.723 25.161 35.145t38.29 17.152 39.717 3.986 31.707-2.011l13.129-2.304q0 21.723 0.293 50.871t0.293 30.866q0 10.277-7.424 17.152t-22.857 3.986q-132.571-43.995-216.283-158.574t-83.712-258.011q0-119.442 58.843-220.27t159.707-159.707 220.27-58.843 220.27 58.843 159.707 159.707 58.843 220.27z" p-id="3347" />
</svg>
複製程式碼


重點來了,那麼我們用symbols包裝後是這個樣子的:

<svg xmlns="http://www.w3.org/2000/svg">
  <symbol id="svg-github"  viewBox="0 0 1024 1024">
    <title>github</title>
    <path style="fill-rule: evenodd;" d="M941.714 512q0 143.433-83.712 258.011t-216.283 158.574q-15.433 2.853-22.565-3.986t-7.131-17.152v-120.576q0-55.442-29.696-81.152 32.585-3.438 58.587-10.277t53.723-22.272 46.299-37.998 30.281-60.014 11.703-86.016q0-69.157-45.129-117.723 21.138-52.005-4.571-116.553-16.018-5.157-46.299 6.29t-52.553 25.161l-21.723 13.714q-53.138-14.848-109.714-14.848t-109.714 14.848q-9.143-6.29-24.283-15.433t-47.726-22.016-49.152-7.717q-25.161 64.585-3.986 116.553-45.129 48.567-45.129 117.723 0 48.567 11.703 85.723t29.989 60.014 46.007 38.29 53.723 22.272 58.587 10.277q-22.857 20.553-28.014 58.843-11.995 5.705-25.71 8.558t-32.585 2.853-37.413-12.288-31.707-35.73q-10.862-18.286-27.721-29.696t-28.27-13.714l-11.447-1.719q-11.995 0-16.567 2.56t-2.853 6.583 5.157 8.009 7.424 6.839l3.986 2.853q12.581 5.705 24.869 21.723t17.993 29.147l5.705 13.129q7.424 21.723 25.161 35.145t38.29 17.152 39.717 3.986 31.707-2.011l13.129-2.304q0 21.723 0.293 50.871t0.293 30.866q0 10.277-7.424 17.152t-22.857 3.986q-132.571-43.995-216.283-158.574t-83.712-258.011q0-119.442 58.843-220.27t159.707-159.707 220.27-58.843 220.27 58.843 159.707 159.707 58.843 220.27z" p-id="3347" />
 </symbol>
</svg>
複製程式碼

那麼問題又來了,我們直接在頁面上引用,就完事了嗎?結果是否定的,請我慢慢道來:

<body>
	<svg xmlns="http://www.w3.org/2000/svg">
	  <symbol id="svg-github"  viewBox="0 0 1024 1024">
	    <title>github</title>
	    <path style="fill-rule: evenodd;" d="M941.714 512q0 143.433-83.712 258.011t-216.283 158.574q-15.433 2.853-22.565-3.986t-7.131-17.152v-120.576q0-55.442-29.696-81.152 32.585-3.438 58.587-10.277t53.723-22.272 46.299-37.998 30.281-60.014 11.703-86.016q0-69.157-45.129-117.723 21.138-52.005-4.571-116.553-16.018-5.157-46.299 6.29t-52.553 25.161l-21.723 13.714q-53.138-14.848-109.714-14.848t-109.714 14.848q-9.143-6.29-24.283-15.433t-47.726-22.016-49.152-7.717q-25.161 64.585-3.986 116.553-45.129 48.567-45.129 117.723 0 48.567 11.703 85.723t29.989 60.014 46.007 38.29 53.723 22.272 58.587 10.277q-22.857 20.553-28.014 58.843-11.995 5.705-25.71 8.558t-32.585 2.853-37.413-12.288-31.707-35.73q-10.862-18.286-27.721-29.696t-28.27-13.714l-11.447-1.719q-11.995 0-16.567 2.56t-2.853 6.583 5.157 8.009 7.424 6.839l3.986 2.853q12.581 5.705 24.869 21.723t17.993 29.147l5.705 13.129q7.424 21.723 25.161 35.145t38.29 17.152 39.717 3.986 31.707-2.011l13.129-2.304q0 21.723 0.293 50.871t0.293 30.866q0 10.277-7.424 17.152t-22.857 3.986q-132.571-43.995-216.283-158.574t-83.712-258.011q0-119.442 58.843-220.27t159.707-159.707 220.27-58.843 220.27 58.843 159.707 159.707 58.843 220.27z" p-id="3347" />
	 </symbol>
	</svg>
</body>
複製程式碼

clipboard.png

肯定有同學想問了,該如何擺正姿勢,正確的使用它呢?高潮部分來了:

clipboard.png

該如何以正確的姿勢插入SVG Sprites?

clipboard.png

<body>
	<svg xmlns="http://www.w3.org/2000/svg" style="display:none">
	  <symbol id="svg-github"  viewBox="0 0 1024 1024">
	    <title>github</title>
	    <path  d="M941.714 512q0 143.433-83.712 258.011t-216.283 158.574q-15.433 2.853-22.565-3.986t-7.131-17.152v-120.576q0-55.442-29.696-81.152 32.585-3.438 58.587-10.277t53.723-22.272 46.299-37.998 30.281-60.014 11.703-86.016q0-69.157-45.129-117.723 21.138-52.005-4.571-116.553-16.018-5.157-46.299 6.29t-52.553 25.161l-21.723 13.714q-53.138-14.848-109.714-14.848t-109.714 14.848q-9.143-6.29-24.283-15.433t-47.726-22.016-49.152-7.717q-25.161 64.585-3.986 116.553-45.129 48.567-45.129 117.723 0 48.567 11.703 85.723t29.989 60.014 46.007 38.29 53.723 22.272 58.587 10.277q-22.857 20.553-28.014 58.843-11.995 5.705-25.71 8.558t-32.585 2.853-37.413-12.288-31.707-35.73q-10.862-18.286-27.721-29.696t-28.27-13.714l-11.447-1.719q-11.995 0-16.567 2.56t-2.853 6.583 5.157 8.009 7.424 6.839l3.986 2.853q12.581 5.705 24.869 21.723t17.993 29.147l5.705 13.129q7.424 21.723 25.161 35.145t38.29 17.152 39.717 3.986 31.707-2.011l13.129-2.304q0 21.723 0.293 50.871t0.293 30.866q0 10.277-7.424 17.152t-22.857 3.986q-132.571-43.995-216.283-158.574t-83.712-258.011q0-119.442 58.843-220.27t159.707-159.707 220.27-58.843 220.27 58.843 159.707 159.707 58.843 220.27z" p-id="3347" />
	 </symbol>
	</svg>
	1、使用方式一
	<svg class="svg-icon">
		 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#svg-github" />
	</svg>
	2、使用方式二,外鏈式引入
	<svg class="svg-icon2">
		 <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="./icon.svg#svg-github" />
	</svg>
	<style>
		.svg-icon2{
			fill:#06c; //還可以設定圖示的種顏色哦
		}
	</style>
</body>
複製程式碼


可能大家就有點疑惑了,為什麼這樣引入圖示會顯示呢?因為要顯示圖示,我們還需要使用<use>元素, 通俗的講就是你定義了一組圖形物件(使用<symbol>元素)之後,可以使用<use>元素來對它進行無限次例項化展示。你使用xlink:href屬性來指定你想要展示哪一組圖示(相當於css圖片精靈中的background-position),這裡,我們要展示的是id為#svg-github的<symbol>,

細心的寶寶們可能還發現了style="display:none",你可以把它理解為是css sprite裡的圖片base64轉化後的檔案,先宣告瞭變數存放起來了,,而方法二裡的xlink:href="./icon.svg#svg-github",可以理解為是css sprite裡我們background-image 引入圖片一樣,而 #svg-github 就是background-position裡的座標, 還有顏色的改變,我們可以直接在svg內的 path上寫行內式 fill="#06c"、style="fill:#06c";都是可以的,在維護上,是不是比圖片更加方便呢???

當然啦,大家都懂的,越漂亮的妹子追的人越多啦,程式碼也一樣,越好用的東西往往也是不可能那麼完美啦,看到這裡,是不是覺得想罵娘呢?白看你說這麼多廢話,最後不能用,坑爹……

 別慌,其實也沒有那麼糟糕啦 ,**SVG只在IE9以上支援;所以如果你需要支援IE8及以下的瀏覽器**,你需要另外再寫一套降級(例如,使用png圖片方案),隨著科技的發展,IE9以上大多數人還是能接受啦,特別是手機端的使用者,再也不用擔心測試MM來找你,圖示不清晰的問題了啦,是不是很開心,有沒有~~

總結:

svg sprites相比css sprites,不管是在維護和開發的過程中,還是在使用者體驗、效能、專案迭代程式碼維護上都比css sprites方便,更高效便捷;

svg sprites優缺點:
  • svg sprites使用xlink:href #id的方式獲取,便於維護和擴充套件,因為小圖的id不會隨便改動;
  • 方便改變圖片顏色,通過設定fill:顏色值,隨意改變小圖顏色;
  • IE9以上支援。
css sprites優缺點:
  • css sprites使用background-position不便於維護和擴充套件、定位不精確等問題,例如:在後期專案迭代中我們需要刪除其中一個小圖,那麼排在它後面的小圖位置都要移動,需要再次修改csss樣式,或每次都要開啟PS刪除某圖示再匯出;
  • 無法修改小圖顏色,要UI設計師調整後替換,過程漫長效率低;
  • 在移動端的大屏手機圖示會模糊,影響體驗。

âå®å®å¥½å¼å¿âçå¾çæç´¢ç»æ

今天的分享就到這裡,如果文章中有不對之處,煩請各位大神扶正。如果你覺得這篇文章對你有所幫助,請記得點贊哦~(^_^)

想更詳細的瞭解我?還有更多疑惑?那就關注下方公眾號,直接向作者提問吧。

該如何以正確的姿勢插入SVG Sprites?

作者:蘇南 - 首席填坑官
交流群:912594095,公眾號:honeyBadger8
本文原創,著作權歸作者所有。商業轉載請聯絡@IT·平頭哥聯盟獲得授權,非商業轉載請註明原連結及出處。




相關文章