这篇文章发布于 2013年09月22日,星期日,10:19,归类于 SVG相关。 阅读 163421 次, 今日 1 次 29 条评论
by zhangxinxu from http://www.zhangxinxu.com
本文地址:http://www.zhangxinxu.com/wordpress/?p=3678
一、SVG前言
再一次拿可缩放矢量图形SVG(Scalable Vector Graphics)说事,对SVG有所关注的同行应该都知道,IE8-以及Android 2.3默认浏览器是不支持SVG的,实际项目,这些浏览器,至少IE8浏览器还没有到不管不问的时候,因此,在使用视网膜显示友好的SVG同时,我们还要做一点优雅降级,使IE8等考古价值浏览器也能手染余香。
本文内容参考自CSS-tricks SVG fallbacks一文,该文章在介绍一种新的SVG降级技术的同时,把以前Using SVG中提到的技术又总结了一遍。大集合什么的我做喜欢了,以后不要找来找去,因此,这里,我按照个人的理解,配合自己的一些实际测试,分享下。
本文内容当下可能不温不火,但明年的今天,估计就不一样了,记住这里,随时到访。
二、svg image标签降级技术
这是一个名叫Alexey Ten首先提出来的,类似下面的代码:
<svg width="96" height="96"> <image xlink:href="svg.svg" src="svg.png" width="96" height="96" /> </svg>
若对上面代码效果感兴趣,您可以狠狠地点击这里:svg image标签降级技术demo
现代浏览器下,例如Chrome下,就是SVG形式显示,如下截图:
IE7下则是png图片显示的效果,如下截图:
上面这个技术是非常巧妙的,其创意借鉴了Jake Archibald的一个研究,即所有浏览器,包括IE,会把image
标签渲染成img
标签,而SVG中的image
作用是:
Provides a way to display a graphics image on the screen.
也就是提供在屏幕上显示一个图形图像的方法。
于是,就有,如果浏览器支持SVG,则SVG显示;对于不支持的浏览器,例如IE8浏览器,会忽略svg
标签的存在,直接渲染image
,在其看来,这就是个img
标签,于是,图像就以svg.png
的形式显示了。
略微的不爽
在iOS 3 and 4设备上,image
降级技术使用的结果是——图片显示。事实上,这两个操作系统的原生浏览器是支持SVG的,比方说以<img src="*.svg">
形式,或者CSS的background-image
;但是其唯独不支持inline
SVG, 就是SVG标签形式嵌在HTML代码中的使用方法是不支持的。于是,导致的结果是,明明可以SVG形式显示的,现在这种用法就只能png
图片显示了,略不爽!
然,iOS 3 and 4设备已是强弩之末(现在已经7
了),面对现实,个人觉得现在已经没必要大惊小怪了。因此,这个技术,个人还是比较推荐的。
资源下载的研究
根据前辈的说法以及自己的验证,IE8-浏览器以及Android 2.3默认浏览器下,只会下载png图片,而Chrome这些噢啦的浏览器,只会下载SVG格式图形。如下:
但是,在IE9~IE11浏览器下,情况就变得有些特殊了。
因为自己没忍住升级到了IE11,因此,没有IE10版本下的加载亲测截图,先用参考文章中的图片示意下:
从上面两个测试截图可以看出,在IE10浏览器下,虽然其标准IE10以及IE9都支持SVG,但是,都发起了png图片的请求。不过,很有意思的是,该请求都被abort了,被阻止了,返回体的数据大小几乎或者就是0b
,也就是没有任何数据返回。流量似乎是省掉了,但是,请求的时间依旧存在,如第一张截图所示的140ms
. 根据某些更准确的测试,这个小小请求,虽然发送和接受的数据不过700多字节,但是,所耗费的时间有数百毫秒之多。如果页面头部有阻塞脚本,问题就比较严重了。
也可能正是由于这种略显奇葩的特性,在IE11浏览器中,情况又有大的改变,下面是我在win7 IE11下的测试截图:
可以看到,IE11浏览器下,虽然显示的只有SVG,但是,png格式图片如若无人地加载进来了,以一种普通图片的姿态被加载进来了。且顺带影响了其小弟模式,如IE9模式也是这副拽模样。
测试结果大汇总
<svg><image> | |
---|---|
<img src=svg.svg> |
Browser | <image> 技术 | 正常 <img> | 下载 |
---|---|---|---|
Chrome 28 | SVG | SVG | 仅SVG |
IE 8 | PNG | — | 仅PNG (via) |
IE 9 | SVG | SVG | 阻断.png , 但仍耗费时间 |
IE 10 | SVG | SVG | 也是声称阻断 – 但是看上去两者都下载 |
IE 11 | SVG | SVG | 或阻断或不阻断 (都不靠谱) |
iPhone 3GS (iOS 3) | PNG | SVG | 需要测试 |
iPhone 4 (iOS 4) | PNG | SVG | 仅PNG (来自) |
iPhone 4S (iOS 5) | SVG | SVG | 需要测试 |
iPhone 5 (iOS 6) | SVG | SVG | 仅SVG |
Android 2.3 | PNG | — | 仅PNG (来自) |
Android 4 | SVG | SVG | 仅SVG (来自) |
Firefox 22 | SVG | SVG | 仅SVG |
三、其他方式下的降级技术
1. 如果你使用SVG作为background-image
Modernizr有一个SVG测试,可以判定设备是否支持SVG,于是,我们就可以通过在HTML元素上添加特定的类名(eg. no-svg
),做不同的样式控制。
.my-element { background-image: url(image.svg); } .no-svg .my-element { background-image: url(image.png); }
这样就不会出现双下载的问题了。
但是,Modernizr毕竟是个外部依赖,且貌似膘肥体键,真要实际应用,不合适的来~
下面有个更优的方法,利用CSS支持的伪hack,如下使用:
.my-element { background-image: url(fallback.png); background-image: url(image.svg), none; }
其利用的技术是CSS3多背景,这是一个经验式技术,我们通过各种观察或者积累发现,浏览器只要支持了多背景,几乎无一例外支持SVG. 于是,浏览器认识url(image.svg), none
这个多背景声明,就使用SVG,否则,降级使用上面的png
背景。很赞的match~
类似技术,我之前也介绍过,稍等,让我找找~
Get it! 此文为:“小tip:巧用CSS3属性作为CSS hack”。两年多前的了,唏嘘感叹时间流逝之快啊~~
2. 如果你使用SVG作为<svg>
首推本文一开始介绍的<image>技术,对于inline
SVG轻微的降低支持问题(指针对ios3/ios4)设备,我个人觉得大可不必在意。
<svg width="96" height="96"> <image xlink:href="svg.svg" src="svg.png" width="96" height="96" /> </svg>
David Ensinger发表过一项技术,是在SVG中使用<foreignObject>
标签。呈现效果还不赖,但问题是,无论哪个浏览器,俱进派还是顽固派都会下载降级的PNG图片,这显然没有上面的<image>技术智能。
当然,你还可以借助Modernizr做些更加灵活的处理:
<svg> ... inline SVG XXX ... </svg> <div class="my-svg-alternate"></div>
.my-svg-alternate { display: none; } .no-svg .my-svg-alternate { display: block; width: 96px; height: 96px; background-image: url(image.png); }
3. 如果你使用SVG作为<object>
使用<object>
标签作为SVG元素本身,对于不支持浏览器,还是需要Modernizr或自己写个判断,或者自己经验的浏览器判断实现:
<object type="image/svg+xml" data="image.svg" class="logo"></object>
.no-svg .logo { display: block; width: 96px; height: 96px; background-image: url(image.png); }
4. 如果你使用SVG作为<img>
Scott Jehl喜欢这么做:
<img src="image.svg" onerror="this.src=image.png">
HTML混杂行为,如果你是个具有分离癖好的人,上面的方法可能会让你揪心,你可以直接Modernizr的JS API,在脚本中判断处理,类似下面:
if (!Modernizr.svg) { $("img[src$='.svg']").attr("src", fallback); }
如果上面代码中的fallback
是个URL字符串,你可以把这个字符串放在data-fallback
中,然后,你就可以根据你的实际需要,例如,根据后缀做智能判断加载等。
SVGeezy就是个专门做这种事情的JS库。
或者,你藏个隐藏的DIV,在需要降级显示的时候就显示,上面有出现过……
四、SVG结语
从最近我对国外一些知名前端网站的文章观察来看,SVG相关的内容比重越来越大,去年是满屏的响应式,SO,我似乎嗅到了一点技术流行趋势的味道。国内前端技术的流行普遍具有滞后性,差不多1~2年的样子。因此,本文内容,对于很大一部分同行而言,可能就是“哦~”一下,不打紧。您可以先记住这里,等明年这个时候,或者明年的明年的这个时候,当你发现你要折腾SVG的时候,再来围观围观,希望到时,本文的一些小技术不会过时,(*^__^*) 嘻嘻……
感谢阅读,欢迎纠错!
本文为原创文章,转载请注明来自张鑫旭-鑫空间-鑫生活[http://www.zhangxinxu.com]
本文地址:http://www.zhangxinxu.com/wordpress/?p=3678
(本篇完)
- 未来必热:SVG Sprites技术介绍 (0.446)
- 见多识广:CodePen项目网站简介 (0.429)
- 渐进式jpeg(progressive jpeg)图片及其相关 (0.125)
- 翻译 - 逐渐消失的Flash网站 (0.072)
- CSS "渐进增强"在web制作中常见应用举例 (0.072)
- RGBA颜色与兼容性的半透明背景色 (0.072)
- CSS页面重构之“门派”之分 (0.072)
- 翻译 - CSS高峰会议内容精选 (0.072)
- CSS3 Transitions, Transforms和Animation使用简介与应用展示 (0.072)
- JS护航下CSS3效果的渐进增强使用 (0.072)
- 介绍一种全新的clipPath Sprites小图标技术 (RANDOM - 0.017)
纠正一个小错误,也许是兼容性问题导致的。上面这句我在ie7上测试无法显示png图片,给png图片的路径加上单引号解决了。
最新标准已经放弃了 xlink 。也就是说,只要 。很多人还在用过时的标准。
太强了。。
第一眼看的时候忽略了 xlink:href=”svg.svg”,以为只有src。2333
大神你好,我希望在svg的绘图区域首先放置一张图片作为背景,然后在上面绘制其他形状,可以无论是用还是,图片都无法显示,只能显示出一张破损图片的logo,试过很多方法都无法解决,可否指点一二?浏览器是Chrome,前端开发用的是React
viewbox尺寸是不是不一致啊?
赞!?
厉害!
受教
svg中能放置一个input吗
hi,Android手机(v4.1.1) qq浏览器(v4.5.2)使用方法三中的第1个:
.my-element {
background-image: url(fallback.png);
background-image: url(image.svg), none;
}
不加png之前,svg无法显示,加了也无法显示,是不是QQ浏览器自以为是支持SVG,其实是不支持的?所以加了png之后和不加是一样的?这样的问题怎么解决?
这样降级行不行?
我测试了下,在chrome 44.0.2368.0,firefox37.0.2,ie8+上是兼容的
代码掉了?
我想让这个image变灰色,可以考虑再换个图片,但是图片太多,不利于维护!
多背景支持,显示顺序是前面的在上
.my-element {
background-image: url(fallback.png);
background-image: url(image.svg), none;
}
即使浏览器支持多背景,还是png在上。
还有一个问题,就是
这样svg的颜色如何设置?
第1个声明被第2个替代(如果认识),则第1条声明不会显示背景。
想问问那个捐赠共勉的二维码是怎么生成的
烦躁啊
用了raphaeljs 这个渲染出来 有兼容性问题呢。
目前在做一个类似visio的在线流程图编辑器,做了大概有7 8个月了。项目逻辑部分基本上已经完了,用的是zrender.js 哎 感觉是交换上 和 缺乏css3的支持上 太乏力了。不晓得SVG在这上面表现的如何
svg还有一个与js交互的功能,有些方法那些交互操作就失效了,可以补充吗?谢谢!
image.png是自己加进去的一个图片吗?我怎么保证它跟我svg里面自己画的相同啊?
你与js交互是怎么实现的,可以说一下吗?谢谢
@hhm 1. SVG在任意的矢量软件中打开(在线SVG编辑工具亦可),可以存储为png格式。
2. JS交互指?没看明白,就跟普通的DOM元素交互类似。
我svg是在js文件里面通过ajax从后台取得数据动态画出来的,怎么存储为png格式?
最近也在做SVG ,谢谢分享
在retina屏上使用svg效果的确相当舒服啊
Hey,你的RSS页面异常了~~~
@AliChow 非常感谢提醒,现已修复!
因为在研究mxGraph,所以svg也都在研究,svg刚成为w3c标准,估计未来它的比重将大大增进
最近也在做SVG,直接用的raphael.js,IE下是用VML,感觉速度还不错的