利用動態viewport+rem制作一張自適應的svg雪碧圖icon
先看下主流瀏覽器 、手機的尺寸和分辨率
主流瀏覽器和手機的尺寸

移動端雪碧圖的痛點-不能自適應
移動端的icon大小不是不定的,如果用px固定住,在高分辨率手機中就會變得很小在低分辨率手機中就會變得很大。
所以手機都拿icon圖標需要用百分比來或者用rem布局來調整icon的大小。
background-position百分比計算公式
x:(容器的寬度-圖片的寬度)x (50%) y:(容器的高度-圖片的高度)x (30%)
比如:容器是width:600px;height:600px;而圖片是width:200px;height:200px;
.icon{ width: 600px; height: 200px; background:#FFF url(image) no-repeat fixed 50% 30%; }

so:
background-position:0% 0%;表示左上角對齊
background-position:100% 0%;表示右上角對齊
動態viewport
動態viewport最初是由手淘使用來解決適應各種手機分辨率的一個解決方案:
會根據手機的分辨率和比率rate生成一個最佳的viewpoint和相對應基準的font-size大小;
viewport.js
!function(win) { function resize() { var domWidth = domEle.getBoundingClientRect().width; if(domWidth / v > 540){ domWidth = 540 * v; } win.rem = domWidth / 10; domEle.style.fontSize = win.rem + "px"; var rem= win.rem; } var v, initial_scale, timeCode, dom = win.document, domEle = dom.documentElement, viewport = dom.querySelector('meta[name="viewport"]'), flexible = dom.querySelector('meta[name="flexible"]'); if (viewport) { var o = viewport.getAttribute("content").match(/initial\-scale=(["']?)([\d\.]+)\1?/); if(o){ initial_scale = parseFloat(o[2]); v = parseInt(1 / initial_scale); } } else if(flexible) { var o = flexible.getAttribute("content").match(/initial\-dpr=(["']?)([\d\.]+)\1?/); if (o) { v = parseFloat(o[2]); initial_scale = parseFloat((1 / v).toFixed(2)) } } if (!v && !initial_scale) { var n = (win.navigator.appVersion.match(/android/gi), win.navigator.appVersion.match(/iphone/gi)); v = win.devicePixelRatio; v = n ? v >= 3 ? 3 : v >= 2 ? 2 : 1 : 1, initial_scale = 1 / v } //沒有viewport標簽的情況下 if (domEle.setAttribute("data-dpr", v), !viewport) { if (viewport = dom.createElement("meta"), viewport.setAttribute("name", "viewport"), viewport.setAttribute("content", "initial-scale=" + initial_scale + ", maximum-scale=" + initial_scale + ", minimum-scale=" + initial_scale + ", user-scalable=no"), domEle.firstElementChild) { domEle.firstElementChild.appendChild(viewport) } else { var m = dom.createElement("div"); m.appendChild(viewport), dom.write(m.innerHTML) } } win.dpr = v; win.addEventListener("resize", function() { clearTimeout(timeCode), timeCode = setTimeout(resize, 300) }, false); win.addEventListener("pageshow", function(b) { b.persisted && (clearTimeout(timeCode), timeCode = setTimeout(resize, 300)) }, false); resize(); }(window);
rem
CSS3的出現,他同時引進了一些新的單位,包括我們今天所說的rem。在W3C官網上是這樣描述rem的——“font size of the root element” 。
關于rem兩個傳送門
http://www.w3cplus.com/css3/define-font-size-with-css3-rem
http://xiaoho.com/webapp-font-size/
真正的高能開始
先上代碼
html
<span class="i i_menu_0"></span>
css
.i { width: 0.8rem; height: 0.8rem; background: url(../images/ico_global.svg) no-repeat; display: inline-block; background-size: 1100%; } .i_menu_0 { background-position: 0% 0%; } .i_menu_1 { background-position: 10% 0%; } .i_menu_2 { background-position: 20% 0%; } .i_menu_3 { background-position: 30% 0%; } .i_menu_4 { background-position: 40% 0%; } .i_menu_5 { background-position: 50% 0%; }
上面有兩個關鍵屬性background-size:1100%;background-position:x% x%;
為什么是1100%
看我的svg圖就知道了

我把一張圖片平均分成11×11的正方形格子,之所以用11×11的正方形格子,
是因為background-position: 0% 0%;是第一個格子,是從零開始計數,所以0%-100%可以平均分成最多11個整數。
當然你可以分成,3×3的格子
0%代表第一個格子
50%代表中間的格子
100%代表最后一個格子

優點
矢量化,文件大小更小,圖標更清晰,加載速度更快
支持漸變背景和支持多色彩icon
調用方便
缺點
由于沒有svg雪碧圖的自動化構建工具,所有的圖片都只能人工維護,維護成本有些高。
兼容性不是很好,但是如果你是做移動端,可以不用考慮這個問題。因為大多移動端都支持svg圖片。

關于svg優雅的降級可以查看張鑫旭的這篇博客
http://www.zhangxinxu.com/wordpress/2013/09/svg-fallbacks/
這次分享就到這里,希望對大家有所幫助!