原文地址
http://css-tricks.com/using-svg/
什么是SVG?
svg是和种矢量图形格式,全拼是:Scalable Vector Graphics (就像AI中的矢量图一样)。在网页上使用SVG很简单,但是有一些东西是你需要知道的。
为什么要用SVG?
- 很小的文件格式
- 缩放到任意大小都不会失真(超小的情况除外)
- 在视网膜屏下完美的显示
- 直接对交互和效果进行控制
获得SVG图形文件
在AI中设计一些自己想要的图案,如下面是一只奇异鸟(Kiwi bird)。
注意在上面的画板中,画板的大小是根据图形大小进行裁剪的(这样导出的SVG方便控制)。
在AI 保存文件的时候选择文件格式为SVG:
在保存的时候 ,会有一个关于SVG的选项,我必须承认我对这些选项不是很了解,这里有一些关于SVG的详细信息:http://www.w3.org/TR/SVGMobile/
,我选择了SVG1.1进行了使用,没有发现任何问题.
在上面的对话框中,你可以点击OK进行存储SVG文件,也可以点击 “SVG代码”按钮,这时打开的是组成这个SVG的一大串代码。
两种方法都是有用的。
在img标签中使用SVG
在IMG标签的SRC属性中添加SVG格式的文件即可:
<img src="kiwi.svg" alt="Kiwi standing on oval">
在AI中,我们的画布大小是612px ✕ 502px.
毫无疑问,这在网页中显示的话将会很大,你可以像控制PNG或JPG等一些普通的图片格式一样来控制SVG文件:
See the Pen lCEux by Chris Coyier (@chriscoyier) on CodePen
浏览器兼容性
除了IE8及以下和Android 2.3以下不支持以外,其它浏览器都是可以肆无忌惮的使用。
如果你希望你的网站在使用SVG并且在所有浏览器里都不出现问题的话,这里有一些方法可以帮助到你:different workshops I’ve done.
有一种方法就是使用Modernizr为k进行检测替换SRC值:
if (!Modernizr.svg) { $(".logo img").attr("src", "images/logo.png"); }
还可以参考David Bushell 的A Primer to Front-end SVG Hacking
另外,SVGeezy插件也可以帮助到你,我们将关注更多的解决该问题(浏览器兼容SVG)的方法。
以background-size方式使用SVG
和控制普通的背景图一样,我们可以使用background-image来控制SVG
<a href="/" class="logo"> Kiwi Corp </a>
.logo { display: block; text-indent: -9999px; width: 100px; height: 82px; background: url(kiwi.svg); background-size: 100px 82px; }
注意上面的CSS中,我们将background-size
设置和LOGO元素一样大,这是非常重要的一步,否则,背景图会根据图片的大小来进行显示。当然,background-size
设置的值要根据图片的宽高比来进行设置,
SVG作为背景的浏览器兼容性
用SVG作为背景和在IMG中使用是一样的,同样在IE8及以下和Android 2.3及以下是用不了的。
可以使用Modernizr来进行判断,相对于使用IMG标签来说,使用背景可以有更多种方法。假设我们只在浏览器支持SVG的时候进行加载,那么这个时候只会有一次的HTTP请求。Modernizr
会在不支持SVG浏览器下的HTML
标签加上一个“no-svg
”的类名,所以我们可以这样解决:
.main-header { background: url(logo.svg) no-repeat top left; background-size: contain; } .no-svg .main-header { background-image: url(logo.png); }
另外,还有一种聪明的方法就是使用多背景(给同一个元素设置普通图片和SVG图片的背景,SVG的背景设置规则要写在后面)。这样做的话,如果浏览器支持SVG,则用后面设置的规则覆盖了前面普通背景图的规则:
body { background: url(fallback.png); background-image: url(image.svg), none; }
使用IMG标签和background-image带来的问题
使用上面的两种方法所带来的问题就是:你没办法用CSS来充分控制SVG的内部结构。但是,别着急,你可以用下面的两种方法来解决这个问题。
在HTML中使用SVG标签
还记得上面的AI中存储SVG图片的时候,我们可以获取SVG代码吗?我们直接把SVG代码放到HTML文档中后,SVG图像照样会正常显示出来。
<body> <!-- paste in SVG code, image shows up! --> </body>
这样做的好处是显而易见的,因为图片在正常显示的情况下不需要进行额外的HTTP请求。这和使用 Data URI有着相同的好处。但是同样也会有坏处,就是写出来的文档会非常的臃肿而且浏览器不会对这样一大堆的东西进行缓存。
优化是首要任务
这可能不会太引起你的注意,但AI所保存的SVG不是最佳的,它生成的SVG里包括DOCTYPE
和一些其它的不需要的代码,我们可以把这些都删掉。虽然SVG文件本身已经很小了,但我们能将它优化的更小不是更好吗?
用CSS来充分的控制SVG
让我们打开SVG文件来看看它的内部结构吧,其实在SVG标签里面是有些XML标签组成的,在我们所画的图(奇异鸟)里,包括两个元素,而生的是两个标签,分别是
ellipse
和path
,我们可以像在一些普通HTML元素上一样,分别给它们加上类名,方便以后进行控制。
<svg ...> <ellipse class="ground" .../> <path class="kiwi" .../> </svg>
现在我们就可以用CSS来控制SVG里的每一部分了。这里需要注意的是,针对SVG元素,有一套独有的CSS规则,比如说,设置填充色不是background-color
属性,而是fill
属性,下面的代码是使用:hover
伪类来让小鸟变幻颜色:
.kiwi { fill: #94d31b; } .kiwi:hover { fill: #ace63c; }
更让人兴奋的是,还可以针对SVG使用滤镜,比如说添加一个模糊的滤镜:
<svg ...> ... <filter id="pictureFilter" > <feGaussianBlur stdDeviation="5" /> </filter> </svg>
然后在CSS中应用一下即可:
.ground:hover { filter: url(#pictureFilter); }
下面是加了滤镜的效果:
See the Pen SVG with Filters by Chris Coyier (@chriscoyier) on CodePen
关于SVG滤镜的一些资料:
- More on applying filters to SVG
- The best list I could find on SVG-specific CSS properties (specific to Opera)
- SVG filter effects playground (from Microsoft)
SVG标签浏览器兼容性
SVG标签的浏览器兼容性有一套它自己的规则,但其实也是在IE8及以下和Android 2.3及以下不支持。
对于SVG标签,兼容低版本的一种方法:
<svg> ... </svg> <div class="fallback"></div>
然后使用Modernizr:
.logo-fallback { display: none; /* Make sure it's the same size as the SVG takes up */ } .no-svg .logo-fallback { background-image: url(logo.png); }
在object中使用SVG
如果你不喜欢使用SVG标签(记住,使用SVG标签,最终的图像是不会被缓存下来的)。但是使用object则不会出现这个问题:
<object type="image/svg+xml" data="kiwi.svg" class="logo"> Kiwi Logo <!-- fallback image in CSS --> </object>
对于不支持SVG的浏览器,使用Modernizr这样进行控制:
.no-svg .logo { width: 200px; height: 164px; background-image: url(kiwi.png); }
这样使用很好的保证了兼容性并且可以被缓存下来。但是,如果你想用CSS对它进行控制,不可以像以前一样在你的文档中使用外部的样式或者style
标签,你需要在SVG文件中使用style
才能对它进行控制:
<svg ...> <style> /* SVG specific fancy CSS styling here */ </style> ... </svg>
在外部样式控制object中的SVG
有一种可以加载外部样式文件的方法,这种方法可以在保证很好可读性且图片可以被缓存。这种方法只适用于在object中使用SVG,你需要把下面的这段代码放到SVG开始标签之前:
<?xml-stylesheet type="text/css" href="svg.css" ?>
如果你把上面的代码放在HTML中,此时你的页面会发出一个错误警告,甚至不会继续渲染页面。如果你是以IMG标签或者背景图的方式使用的SVG,将不会发出这样的警告,但是它将不会正常工作。
SVG -> Data URI
一种使SVG变的更小的方法就是将它变成Data URI。Mobilefish.com 有一个在线转换的工具。你只需要把你的SVG代码拷过来转换一下即可:
你可以使用我们上面说到的方法来使用这个DATA URI(除了SVG标签),比如:
IMG标签的方式
<img src="data:image/svg+xml;base64,[data]>
CSS调用
.logo { background: url(data:image/svg+xml;base64,[data]); }
object标签的方式
<object type="image/svg+xml" data="data:image/svg+xml;base64,[data]> fallback </object>
译者结语
本人才疏学浅,文章难免翻译有误,如果大家发现,希望指出,谢谢!