Html 对于 SVG 文件,我是否使用 <img>、<object> 或 <embed>?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4476526/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Do I use <img>, <object>, or <embed> for SVG files?
提问by artlung
Should I use <img>
, <object>
, or <embed>
for loading SVG files into a page in a way similar to loading a jpg
, gif
or png
?
我是否应该使用<img>
,<object>
或<embed>
以类似于加载jpg
,gif
或的方式将 SVG 文件加载到页面中png
?
What is the code for each to ensure it works as well as possible? (I'm seeing references to including the mimetype or pointing to fallback SVG renderers in my research and not seeing a good state of the art reference).
每个代码是什么以确保它尽可能好地工作?(我在我的研究中看到了包括 mimetype 或指向后备 SVG 渲染器的参考,但没有看到良好的最新技术参考)。
Assume I am checking for SVG support with Modernizrand falling back (probably doing a replacement with a plain <img>
tag)for non SVG-capable browsers.
假设我正在检查Modernizr对 SVG 的支持,并<img>
为不支持 SVG 的浏览器回退(可能用普通标签替换)。
回答by Erik Dahlstr?m
I can recommend the SVG Primer (published by the W3C), which covers this topic: http://www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#SVG_in_HTML
我可以推荐 SVG Primer(由 W3C 发布),它涵盖了这个主题:http: //www.w3.org/Graphics/SVG/IG/resources/svgprimer.html#SVG_in_HTML
If you use <object>
then you get raster fallback for free*:
如果您使用,<object>
那么您将免费获得栅格回退*:
<object data="your.svg" type="image/svg+xml">
<img src="yourfallback.jpg" />
</object>
*) Well, not quite for free, because some browsers download both resources, see Larry's suggestion below for how to get around that.
*) 好吧,不是免费的,因为有些浏览器会下载这两种资源,请参阅下面 Larry 的建议,了解如何解决这个问题。
2014 update:
2014年更新:
If you want a non-interactive svg, use
<img>
with script fallbacks to png version (for older IE and android < 3). One clean and simple way to do that:<img src="your.svg" onerror="this.src='your.png'">
.This will behave much like a GIF image, and if your browser supports declarative animations (SMIL) then those will play.
If you want an interactive svg, use either
<iframe>
or<object>
.If you need to provide older browsers the ability to use an svg plugin, then use
<embed>
.For svg in css
background-image
and similar properties, modernizris one choice for switching to fallback images, another is depending on multiple backgrounds to do it automatically:div { background-image: url(fallback.png); background-image: url(your.svg), none; }
Note: the multiple backgrounds strategy doesn't work on Android 2.3 because it supports multiple backgrounds but not svg.
如果您想要非交互式 svg,请使用
<img>
脚本回退到 png 版本(对于较旧的 IE 和 android < 3)。一种干净而简单的方法来做到这一点:<img src="your.svg" onerror="this.src='your.png'">
.这将表现得非常像 GIF 图像,如果您的浏览器支持声明性动画 (SMIL),那么这些将播放。
如果您想要交互式 svg,请使用
<iframe>
或<object>
。如果您需要为旧版浏览器提供使用 svg 插件的能力,请使用
<embed>
.对于 css 中的 svg
background-image
和类似属性,modernizr是切换回退图像的一种选择,另一种是依赖多个背景自动执行:div { background-image: url(fallback.png); background-image: url(your.svg), none; }
注意:多背景策略不适用于 Android 2.3,因为它支持多背景但不支持 svg。
An additional good read is this blogposton svg fallbacks.
回答by Christian Landgren
From IE9 and above you can use SVG in a ordinary IMG tag..
从 IE9 及更高版本开始,您可以在普通的 IMG 标签中使用 SVG。
<img src="/static/image.svg">
回答by WGH
<object>
and <embed>
have an interesting property: they make it possible to obtain a reference to SVG document from outer document (taking same-origin policy into account). The reference can then be used to animate the SVG, change its stylesheets, etc.
<object>
并且<embed>
有一个有趣的特性:它们可以从外部文档中获取对 SVG 文档的引用(考虑同源策略)。然后可以使用引用来为 SVG 设置动画、更改其样式表等。
Given
给定的
<object id="svg1" data="/static/image.svg" type="image/svg+xml"></object>
You can then do things like
然后你可以做这样的事情
document.getElementById("svg1").addEventListener("load", function() {
var doc = this.getSVGDocument();
var rect = doc.querySelector("rect"); // suppose our image contains a <rect>
rect.setAttribute("fill", "green");
});
回答by Roberth Solís
The best option is to use SVG Images on different devices :)
最好的选择是在不同的设备上使用 SVG 图像:)
<img src="your-svg-image.svg" alt="Your Logo Alt" onerror="this.src='your-alternative-image.png'">
回答by Scribblemacher
Use srcset
用 srcset
Most current browsers today support the srcset
attribute, which allows specifying different images to different users. For example, you can use it for 1x and 2x pixel density, and the browser will select the correct file.
目前srcset
大多数浏览器都支持属性,它允许为不同的用户指定不同的图像。例如,您可以将其用于 1x 和 2x 像素密度,浏览器将选择正确的文件。
In this case, if you specify an SVG in the srcset
and the browser doesn't support it, it'll fallback on the src
.
在这种情况下,如果您在 中指定了 SVGsrcset
并且浏览器不支持它,它将回退到src
.
<img src="logo.png" srcset="logo.svg" alt="My logo">
This method has several benefits over other solutions:
与其他解决方案相比,此方法有几个优点:
- It's not relying on any weird hacks or scripts
- It's simple
- You can still include alt text
- Browsers that support
srcset
should know how to handle it so that it only downloads the file it needs.
- 它不依赖于任何奇怪的黑客或脚本
- 这很简单
- 您仍然可以包含替换文字
- 支持的浏览器
srcset
应该知道如何处理它,以便它只下载它需要的文件。
回答by Waruyama
If you need your SVGs to be fully styleable with CSS they have to be inline in the DOM. This can be achieved through SVG injection, which uses Javascript to replace a HTML element (usually an <img>
element) with the contents of an SVG file after the page has loaded.
如果您需要您的 SVG 完全可以使用 CSS 进行样式设置,则它们必须内联在 DOM 中。这可以通过 SVG 注入来实现,它使用 Javascript<img>
在页面加载后用 SVG 文件的内容替换 HTML 元素(通常是一个元素)。
Here is a minimal example using SVGInject:
这是一个使用SVGInject的最小示例:
<html>
<head>
<script src="svg-inject.min.js"></script>
</head>
<body>
<img src="image.svg" onload="SVGInject(this)" />
</body>
</html>
After the image is loaded the onload="SVGInject(this)
will trigger the injection and the <img>
element will be replaced by the contents of the file provided in the src
attribute. This works with all browsers that support SVG.
加载图像后,onload="SVGInject(this)
将触发注入,<img>
元素将被src
属性中提供的文件内容替换。这适用于所有支持 SVG 的浏览器。
Disclaimer: I am the co-author of SVGInject
免责声明:我是 SVGInject 的合著者
回答by LazerBanana
I would personally use an <svg>
tag because if you do you have full control over it. If you do use it in <img>
you don't get to control the innards of the SVG with CSS etc.
我个人会使用<svg>
标签,因为如果你这样做,你可以完全控制它。如果您确实在其中使用它,<img>
则无法使用 CSS 等来控制 SVG 的内部结构。
another thing is browser support.
另一件事是浏览器支持。
Just open your svg
file and paste it straight into the template.
只需打开您的svg
文件并将其直接粘贴到模板中即可。
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 3400 2700" preserveAspectRatio="xMidYMid meet" (click)="goHome();">
<g id="layer101">
<path d="M1410 2283 c-162 -225 -328 -455 -370 -513 -422 -579 -473 -654 -486 -715 -7 -33 -50 -247 -94 -475 -44 -228 -88 -448 -96 -488 -9 -40 -14 -75 -11 -78 2 -3 87 85 188 196 165 180 189 202 231 215 25 7 129 34 230 60 100 26 184 48 185 49 4 4 43 197 43 212 0 10 -7 13 -22 9 -13 -3 -106 -25 -208 -49 -102 -25 -201 -47 -221 -51 l-37 -7 8 42 c4 23 12 45 16 49 5 4 114 32 243 62 129 30 240 59 246 66 10 10 30 132 22 139 -1 2 -110 -24 -241 -57 -131 -33 -240 -58 -242 -56 -6 6 13 98 22 107 5 4 135 40 289 80 239 61 284 75 307 98 14 15 83 90 153 167 70 77 132 140 139 140 7 0 70 -63 141 -140 70 -77 137 -150 150 -163 17 -19 81 -39 310 -97 159 -41 292 -78 296 -82 8 -9 29 -106 24 -111 -1 -2 -112 24 -245 58 -134 33 -245 58 -248 56 -6 -7 16 -128 25 -136 5 -4 112 -30 238 -59 127 -29 237 -54 246 -57 11 -3 20 -23 27 -57 6 -28 9 -53 8 -54 -1 -1 -38 7 -81 17 -274 66 -379 90 -395 90 -16 0 -16 -6 3 -102 11 -57 21 -104 22 -106 1 -1 96 -27 211 -57 115 -31 220 -60 234 -66 14 -6 104 -101 200 -211 95 -111 175 -197 177 -192 1 5 -40 249 -91 542 l-94 532 -145 203 c-220 309 -446 627 -732 1030 -143 201 -265 366 -271 367 -6 0 -143 -183 -304 -407z m10 -819 l-91 -161 -209 -52 c-115 -29 -214 -51 -219 -49 -6 1 32 55 84 118 l95 115 213 101 c116 55 213 98 215 94 1 -3 -38 -78 -88 -166z m691 77 l214 -99 102 -123 c56 -68 100 -125 99 -127 -4 -3 -435 106 -447 114 -4 2 -37 59 -74 126 -38 68 -79 142 -93 166 -13 23 -22 42 -20 42 2 0 101 -44 219 -99z"/>
<path d="M1126 2474 c-198 -79 -361 -146 -363 -147 -2 -3 -70 -410 -133 -805 -12 -73 -20 -137 -18 -143 2 -6 26 23 54 63 27 40 224 320 437 622 213 302 386 550 385 551 -2 2 -165 -62 -362 -141z"/>
<path d="M1982 2549 c25 -35 159 -230 298 -434 139 -203 283 -413 319 -465 37 -52 93 -134 125 -182 59 -87 83 -109 73 -65 -5 20 -50 263 -138 747 -17 91 -36 170 -42 176 -9 8 -571 246 -661 280 -14 6 -7 -10 26 -57z"/>
<path d="M1679 1291 c-8 -11 -71 -80 -141 -153 l-127 -134 -95 -439 c-52 -242 -92 -442 -90 -445 6 -5 38 28 218 223 l99 107 154 0 c85 0 163 -4 173 -10 10 -5 78 -79 151 -162 73 -84 136 -157 140 -162 18 -21 18 4 -2 85 -11 46 -58 248 -105 448 l-84 364 -87 96 c-108 121 -183 201 -187 201 -2 0 -10 -9 -17 -19z m96 -488 c33 -102 59 -189 57 -192 -2 -6 -244 -2 -251 4 -5 6 120 375 127 375 4 0 34 -84 67 -187z"/>
</g>
</svg>
then in your css you can simply eg:
然后在您的 css 中,您可以简单地例如:
svg {
fill: red;
}
Some resource: SVG tips
一些资源:SVG 技巧
回答by Andrew Swift
If you use <img>tags, then webkit based browserswon't display embedded bitmapped images.
如果您使用<img>标签,那么基于 webkit 的浏览器将不会显示嵌入的位图图像。
For any kind of advanced SVG use, including the SVG inline offers by far the most flexibility.
对于任何类型的高级 SVG 使用,包括 SVG 内联提供了迄今为止最大的灵活性。
Internet Explorer and Edge will resize the SVG correctly, but you must specify both the height and width.
Internet Explorer 和 Edge 将正确调整 SVG 的大小,但您必须同时指定高度和宽度。
You can add onclick, onmouseover, etc.inside the svg, to any shape in the SVG: onmouseover="top.myfunction(evt);"
您可以在 svg中将onclick、onmouseover 等添加到 SVG 中的任何形状: onmouseover="top.myfunction(evt);"
You can also use web fontsin the SVG by including them in your regular style sheet.
您还可以通过将Web 字体包含在常规样式表中来在 SVG 中使用它们。
Note: if you are exporting SVG's from Illustrator, the web font names will be wrong.You can correct this in your CSS and avoid messing around in the SVG. For example, Illustrator gives the wrong name to Arial, and you can fix it like this:
注意:如果您从 Illustrator 导出 SVG,则 Web 字体名称将是错误的。您可以在 CSS 中更正此问题,避免在 SVG 中乱七八糟。例如,Illustrator 为 Arial 提供了错误的名称,您可以像这样修复它:
@font-face {
font-family: 'ArialMT';
src:
local('Arial'),
local('Arial MT'),
local('Arial Regular');
font-weight: normal;
font-style: normal;
}
All this works on any browser released since 2013.
所有这些都适用于自 2013 年以来发布的任何浏览器。
For an example, see ozake.com.The whole site is made of SVG's except for the contact form.
有关示例,请参阅ozake.com。除了联系表格之外,整个网站都是由 SVG 组成的。
Warning:Web fonts are imprecisely resized in Safari — and if you have lots of transitions from plain text to bold or italic, there may be a small amount of extra or missing space at the transition points. See my answer at this questionfor more information.
警告:Web 字体在 Safari 中的大小调整不准确——如果您有大量从纯文本到粗体或斜体的过渡,则过渡点处可能会有少量额外或缺失的空间。有关更多信息,请参阅我在此问题上的回答。
回答by ffflabs
My two cents: as of 2019, 93% of browsers in use (and 100% of the last two version of every one of them) can handle SVG in <img>
elements:
我的两分钱:截至 2019 年,93% 的浏览器(以及每个浏览器的最后两个版本的 100%)可以在<img>
元素中处理 SVG :
Source: Can I Use
来源:我可以使用吗
So we couldsay that there's no reason to use <object>
anymore.
所以我们可以说没有理由再使用<object>
了。
Howeverit's still has its pros:
但是它仍然有它的优点:
When inspecting (e.g. with Chrome Dev Tools) you are presented with the whole SVG markup in case you wanted to tamper a bit with it and see live changes.
It provides a very robust fallback implementation in case your browser does not support SVGs (wait, but every one of them does!) which also works if the SVG isn't found. This was a key feature of XHTML2 spec, which is like betamax or HD-DVD
在检查时(例如使用 Chrome 开发工具),您会看到整个 SVG 标记,以防您想对其进行一些改动并查看实时更改。
它提供了一个非常强大的后备实现,以防您的浏览器不支持 SVG(等等,但它们每个都支持!),如果找不到 SVG,它也可以工作。这是 XHTML2 规范的一个关键特性,类似于 betamax 或 HD-DVD
Butthere are also cons:
但也有缺点:
- there isn't an AMP counterpart to
<object>
(tho it's perfectly safe to use it with<amp-img>
and use it inline too. - you shouldn't mix serviceworker fetch handler with any kind of embed, so having an
<object>
tag might keep your PWA from being really offline capable.
- 没有 AMP 对应物
<object>
(虽然使用它<amp-img>
并内联使用它是完全安全的。 - 您不应该将 serviceworker fetch 处理程序与任何类型的 embed 混合使用,因此拥有
<object>
标签可能会使您的 PWA 无法真正脱机。
回答by Artru
Found one solution with pure CSS and without double image downloading. It is not beautiful as I want, but it works.
找到了一种纯 CSS 且无需双重图像下载的解决方案。它不像我想要的那样美丽,但它有效。
<!DOCTYPE html>
<html>
<head>
<title>HTML5 SVG demo</title>
<style type="text/css">
.nicolas_cage {
background: url('nicolas_cage.jpg');
width: 20px;
height: 15px;
}
.fallback {
}
</style>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" width="0" height="0">
<style>
<![CDATA[
.fallback { background: none; background-image: none; display: none; }
]]>
</style>
</svg>
<!-- inline svg -->
<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40">
<switch>
<circle cx="20" cy="20" r="18" stroke="grey" stroke-width="2" fill="#99FF66" />
<foreignObject>
<div class="nicolas_cage fallback"></div>
</foreignObject>
</switch>
</svg>
<hr/>
<!-- external svg -->
<object type="image/svg+xml" data="circle_orange.svg">
<div class="nicolas_cage fallback"></div>
</object>
</body>
</html>
The idea is to insert special SVG with fallback style.
这个想法是插入具有后备样式的特殊 SVG。
More details and testing process you can find in my blog.
您可以在我的博客中找到更多详细信息和测试过程。