利用动态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%;
}
图片来源:www.cnblogs.com/lxin/p/3636302.html
图片来源:www.cnblogs.com/lxin/p/3636302.html

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图就知道了

demosvg.jpg

我把一张图片平均分成11×11的正方形格子,之所以用11×11的正方形格子,
是因为background-position: 0% 0%;是第一个格子,是从零开始计数,所以0%-100%可以平均分成最多11个整数。
当然你可以分成,3×3的格子
0%代表第一个格子
50%代表中间的格子
100%代表最后一个格子

3x3.png

优点

矢量化,文件大小更小,图标更清晰,加载速度更快
支持渐变背景和支持多色彩icon
调用方便

缺点

由于没有svg雪碧图的自动化构建工具,所有的图片都只能人工维护,维护成本有些高。
兼容性不是很好,但是如果你是做移动端,可以不用考虑这个问题。因为大多移动端都支持svg图片。

svg优雅的降级.jpg

关于svg优雅的降级可以查看张鑫旭的这篇博客
http://www.zhangxinxu.com/wordpress/2013/09/svg-fallbacks/

这次分享就到这里,希望对大家有所帮助!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,165评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,503评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,295评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,589评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,439评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,342评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,749评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,397评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,700评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,740评论 2 313
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,523评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,364评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,755评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,024评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,297评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,721评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,918评论 2 336

推荐阅读更多精彩内容

  • 1、困扰多时的问题 在这之前做Web App开发的的时候,在自适应方面一般都是宽度通过百分比,高度以iPhone6...
    阿根廷斗牛阅读 1,223评论 0 3
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,709评论 1 92
  • 文/教育那些事儿 人活一生,自会经历或见闻许许多多的故事。故事在我视野里绽放,我在故事中成长。 (一) 2006年...
    明辉微语阅读 540评论 3 6
  • 懒洋洋地宅家 回家的日子总是无聊而又荒废的,活动范围除了家就是楼下的超市。前两天杨娴约去走沿江路,一开始不是很想去...
    KKallen阅读 379评论 2 1
  • 第一次看见爱情 大约还是在小学 那时的电视剧里 正播放着玫瑰与蝴蝶 那时的我还不懂爱情 但是看见主角接吻 还是会心...
    幻梦邪魂阅读 384评论 6 2