使用 SVG
为什么使用SVG
- 体积小
- 缩放不失真(除非非常小)
- 在retina显示很好
制作SVG
Adobe illustrator
以<img>
方式使用SVG
例如:
<img src="kiwi.svg" alt="Kiwi standing on oval">
浏览器支持
参见:http://caniuse.com/#feat=svg-img
基本上除了IE 8及其以下,和Android 2.3及其以下都支持。
兼容方案一:
if (!Modernizr.svg) {
$(".logo img").attr("src", "images/logo.png");
}
兼容方案二:
<img src="image.svg" onerror="this.onerror=null; this.src='image.png'">
以background-image
方式使用SVG
例如:
<a href="/" class="logo">
Kiwi Corp
</a>
css:
.logo {
display: block;
text-indent: -9999px;
width: 100px;
height: 82px;
background: url(kiwi.svg);
background-size: 100px 82px;
}
浏览器支持
参见:http://caniuse.com/#feat=svg-css
基本上和使用img
标签一致:除了IE 8及其以下,和Android 2.3及其以下都支持。
兼容方案一:Modernizr
.main-header {
background: url(logo.svg) no-repeat top left;
background-size: contain;
}
.no-svg .main-header {
background-image: url(logo.png);
}
这样会比使用img
标签少一次HTTP请求。
兼容方案二:
body {
background: url(fallback.png);
background-image: url(image.svg), none;
}
这是因为浏览器对SVG的支持程度和对多背景的支持程度类似。所以如果浏览器支持多背景图,基本上就支持SVG,第二条css规则就生效,从而覆盖第一条。
问题是
使用上面个两种方式的缺点在于不能用CSS控制SVG的内部结构。用下面的方式就可以:
使用"inline" SVG
<body>
<!-- paste in SVG code, image shows up! -->
</body>
这样就不用发起额外的HTTP请求。和使用Data URI的优点一样,当然缺点也一样。
还可以利用后端语言进行插入:
<?php echo file_get_contents("kiwi.svg"); ?>
使用PHP时,要使用file_get_contents()
,而不能用include()
和include_once()
。because SVG sometimes is exported with <?xml version="1.0" encoding="UTF-8"?> that as the opening line, which will cause the PHP parser to choke on it.
优化SVG文件
用CSS进行控制
可以像编辑HTML标签那样编辑SVG标签,例如:
<svg ...>
<ellipse class="ground" .../>
<path class="kiwi" .../>
</svg>
SVG 元素有独立的CSS属性集。例如:不是background-color
而是 fill
。
.kiwi {
fill: #94d31b;
}
.kiwi:hover {
fill: #ace63c;
}
svg 可以使用filter
<svg ...>
...
<filter id="pictureFilter" >
<feGaussianBlur stdDeviation="5" />
</filter>
</svg>
.ground:hover {
filter: url(#pictureFilter);
}
浏览器支持
参见http://caniuse.com/#feat=svg-html5
基本上也是:除了IE 8及其以下,和Android 2.3及其以下都支持。
兼容方案:利用Modernizr
<svg> ... </svg>
<div class="fallback"></div>
.fallback {
display: none;
/* Make sure it's the same size as the SVG takes up */
}
.no-svg .fallback {
background-image: url(logo.png);
}
以<object>
形式使用SVG
<object type="image/svg+xml" data="kiwi.svg" class="logo">
Kiwi Logo <!-- fallback image in CSS -->
</object>
兼容方案,还是使用Modernizr:
.no-svg .logo {
width: 200px;
height: 164px;
background-image: url(kiwi.png);
}
如果要使用CSS,则不能直接在HTML中应用外部样式表,或是内联样式表。需要将<style>
写到SVG文件中。
<svg ...>
<style>
/* SVG specific fancy CSS styling here */
</style>
...
</svg>
如果需要引用外部样式表,则需要在SVG文件中,
<?xml-stylesheet type="text/css" href="svg.css" ?>
以这种方式引入的样式对于用<img>
或是background-image
方式引入的SVG文件不起作用。
以Data URI 形式使用SVG
在线转换工具:http://www.mobilefish.com/services/base64/base64.php
可以用转换后的结果替换下面的[data]
:
在<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>
如果在转换之前,在SVG中引入了<style>
,那么如果使用<object>
方式使用base64结果,同样会起作用。
Data URI 的格式
Data URI不一定是base64格式。对于SVG来说,可能最好不要用base64格式
Primarily because the native format of SVG is much more repetitive than base64 ends up, it gzips better.
<!-- base64 -->
data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL...
<!-- UTF-8, not encoded -->
data:image/svg+xml;charset=UTF-8,<svg ...> ... </svg>
<!-- UTF-8, optimized encoding for compatibility -->
data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://...'
<!-- Fully URL encoded ASCII -->
data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns%3D%22http%3A//...