我应该使用<img>, <object>,或<embed>加载SVG文件到页面的方式类似于加载jpg, gif或png?

每一个代码是什么,以确保它工作得尽可能好?(在我的研究中,我看到了包括mimetype或指向备用SVG渲染器的参考,但没有看到一个良好的艺术状态参考)。

假设我正在使用Modernizr检查SVG支持,并退回到不支持SVG的浏览器(可能使用普通的<img>标记进行替换)。


当前回答

根据个人经验,我建议在image tag中通过src加载svg文件,如果一个页面上有很多svg图标或动态追加,会变慢,性能变差

<img src="./file.svg"/> is better performance than 

<div><svg>.....</svg></div>

但是如果你想在hover中指定CSS样式,你必须使用embed

其他回答

我的两分:截至2019年,93%的正在使用的浏览器(以及100%的最后两个版本的每个浏览器)可以处理<img>元素中的SVG:

来源:Can I Use

所以我们可以说没有理由再使用<object>了。

然而,它仍然有它的优点:

当检查时(例如使用Chrome Dev Tools),你会看到整个SVG标记,以防你想要篡改它并看到实时变化。 它提供了一个非常健壮的后备实现,以防您的浏览器不支持SVG(等等,但每个浏览器都支持!),如果找不到SVG,它也可以工作。这是XHTML2规范的一个关键特性,它类似于betamax或HD-DVD

但也有缺点:

没有AMP对应的<object>(虽然它是完全安全的使用< AMP -img>和内联使用它。 你不应该混合serviceworker获取处理程序与任何类型的嵌入,所以有一个<object>标签可能会使你的PWA从真正的离线能力。

您可以插入SVG间接使用<img> HTML标签,这是可能的StackOverflow如下所述:

我的电脑上有以下SVG文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="350" height="350" viewBox="0 0 350 350">

  <title>SVG 3 Circles Intersection </title>

    <circle cx="110" cy="110" r="100"
            stroke="red"
            stroke-width="3"
            fill="none"
            />
    <text x="110" y="110" 
          text-anchor="middle"
          stroke="red"
          stroke-width="1px"
          > Label
    </text>
    <circle cx="240" cy="110" r="100" 
            stroke="blue" 
            stroke-width="3"
            fill="none"
            />
    <text x="240" y="110" 
          text-anchor="middle" 
          stroke="blue" 
          stroke-width="1px"
          > Ticket
    </text>
    <circle cx="170" cy="240" r="100" 
            stroke="green" 
            stroke-width="3" 
            fill="none"
            />
    <text x="170" y="240" 
          text-anchor="middle" 
          stroke="green" 
          stroke-width="1px"
          > Vecto
    </text>
</svg>

我已经把这张照片上传到https://svgur.com

上传终止后,我获得了以下URL:

https://svgshare.com/i/kyc.svg

然后我手动(不使用图像图标)添加以下html标签

<img src='https://svgshare.com/i/kyc.svg' title='Intersection of 3 Circles'/>

结果就在下面

使用数据:形象

对于有疑问的用户,可以看到我在插入SVG图像的StackOverflow上编辑以下答案所做的工作

备注-1:SVG文件必须包含<?xml?>元素。在开始时,我只是简单地创建了一个SVG文件,直接以< SVG >标记开始,但什么都不起作用!

备注-2:在开始时,我已经尝试使用编辑工具栏的image图标插入图像。我粘贴我的SVG文件的URL,但StackOverflow不接受这个方法。<img>标签需要手动添加。

我希望这个答案可以帮助其他用户。

以下是我所能找到的将svg插入HTML模板的所有方法的总结,以及它们的区别和主要优缺点:

(((1)))

/* in CSS */
background-image: url(happy.svg);

这种方式既不允许JS交互,也不允许CSS本身 可以对SVG部分进行更细粒度的控制。

(((2)))

<img src="happy.svg" />

就像(((1)))一样,既不允许JS交互,也不允许CSS本身对svg部分有更细粒度的控制。

方法(((1)))和(((2)))只适用于需要静态svg。

注意:当使用<img>标记时,如果您在srcset属性中指定了SVG,而浏览器不支持它,它将自动回退到src属性。

<img src="logo.png" srcset="logo.svg" alt="my logo">

(((3)))

<div>
 <!-- Paste the SVG code directly here. -->
 <svg>...</svg>
 <!-- AKA an inline svg -->
 <!-- would be the same if is created and appended using JavaScript. -->
</div>

此方法没有(((1)))和(((2))中提到的任何警告,但是,此方法使模板代码混乱,并且svg是复制粘贴的,因此它们不会在自己的单独文件中。

((4))

<object data="happy.svg" width="300" height="300"></object>

OR:

<object data="your.svg" type="image/svg+xml">
  <img src="yourfallback.jpg" />
</object>

使用这种方法,SVG将不能使用外部CSS访问,但可以使用JavaScript访问。

((5))

使用iconfu/svg-inject将svg保存在它们自己的单独文件中(以使模板代码更加清晰),现在使用<img>标记添加svg, svg-inject将自动将它们转换为内联svg,因此CSS和JavaScript都可以访问它们。

注1:如果动态添加imgs(使用javascript),此方法也有效。

注2:使用此方法添加的svg也会像图像一样被浏览器缓存。

((6))

使用单个SVG精灵文件,然后使用<use>标记插入它们。这种方式也非常灵活,具有与(((5))相同的效果。这个视频中展示了这个方法(以及其他一些方法)。

((7))

(React特有的方式)将它们转换为React组件(或编写一个加载它们的组件)。

((8))

<embed src="happy.svg" />

根据MDN的说法,大多数现代浏览器已经弃用并删除了对浏览器插件的支持。这意味着如果您希望站点在普通用户的浏览器上可操作,那么依赖<embed>通常是不明智的。

尽管w3schools不推荐<embed>标签,它是唯一让我的svg混合模式和蒙版在Chrome中工作的东西:

<embed src="logo.svg" style="width:100%; height:180px" type="image/svg+xml" />

而Firefox则很好

<svg style="width:100%">
    <use xlink:href="logo.svg#logo"></use>
</svg>

Chrome did not render the gradient: <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="146" version="1.1"> <title>digicraft punchcard logo</title> <defs> <linearGradient id="punchcard-gradient" x1="100%" y1="50%" x2="0%" y2="50%"> <stop offset="0%" style="stop-color:rgb(128,128,128);stop-opacity:0" /> <stop offset="100%" style="stop-color:rgb(69,69,69);stop-opacity:1" /> </linearGradient> <pattern id="punchcard-pattern-v" x="0" y="0" width="21" height="21" patternUnits="userSpaceOnUse"> <rect x="0" y="0" width="20" height="20" fill="skyblue" onClick="mClick(this)" /> </pattern> <pattern id="punchcard-pattern-h" x="0" y="0" width="21" height="145" patternUnits="userSpaceOnUse"> <rect x="0" y="0" width="21" height="20" fill="skyblue" /> <rect x="0" y="20" width="20" height="84" fill="url(#punchcard-pattern-v)" /> <rect x="0" y="105" width="20" height="20" fill="skyblue" /> <rect x="0" y="126" width="21" height="20" fill="skyblue" /> </pattern> <mask id="punchcard-mask" width="10" height="100%"> <rect width="100%" height="146" fill="url(#punchcard-pattern-h)" /> </mask> </defs> <rect x="0" y="0" width="100%" height="159" fill="url(#punchcard-gradient)" mask="url(#punchcard-mask)" /> </svg>

两个浏览器中的<object>和<img>也是如此。

使用<svg>标记更容易,因为您的代码将运行得更快,并且您直接使用svg。要获得只有svg标记,复制svg文件不带xml标记。结果会是这样的:

<svg fill="#000000" xmlns="http://www.w3.org/2000/svg"  viewBox="0 0 16 16" width="64px" height="64px"><path d="M 4.5 2 C 3.675781 2 3 2.675781 3 3.5 L 3 14.484375 L 8 10.820313 L 13 14.484375 L 13 3.5 C 13 2.675781 12.324219 2 11.5 2 Z M 4.5 3 L 11.5 3 C 11.78125 3 12 3.21875 12 3.5 L 12 12.515625 L 8 9.578125 L 4 12.515625 L 4 3.5 C 4 3.21875 4.21875 3 4.5 3 Z"/></svg>