为什么SVG中的<use>元素无法工作?

7

我有一个简单的例子,它存储在image.svg中:

<svg>
  <defs>
    <g id="shape">
      <circle cx="100" cy="100" r="100" />
    </g>
  </defs>
</svg>

然而,将这段代码放入HTML文件中并没有加载任何内容。为什么会这样?
<svg>
  <use xlink:href="#shape" x="10" y="10" />
</svg>

我做错了什么?似乎无法使其正常工作。


Stack Snippets是相互隔离的(因此一个文档中的id不会与另一个文档中的id冲突)。总的来说,这应该是可能的。 - Robert Longson
4个回答

9

如果您正在使用来自另一个文档的元素,则必须指定该文档!

<use xlink:href="#shape" x="10" y="10" />

这意味着“使用当前文档中的#shape元素”。要从另一个文档导入,您需要在xlink:href属性中放置对SVG文件的引用:
<use xlink:href="image.svg#shape" x="10" y="10" />

显然你需要检查这里的路径是否正确。请注意,虽然有polyfills可用,但任何版本的Internet Explorer都不支持此功能。


7

对于外部的SVG文件,您需要使用命名空间...我已经添加了填充以呈现圆形,否则它会是透明的:

<svg xmlns="http://www.w3.org/2000/svg" >
  <symbol id="shape" width="200" height="200" viewbox="0 0 200 200">
    <circle cx="100" cy="100" r="100" fill="currentColor" />
  </symbol>
  <text y="20">Symbol above will not render unless referenced by use element</text>
</svg>

然后当您引用它时,您需要使用xlink的正确命名空间:

svg.defs-only {
  display:block; position: absolute; 
  height:0; width:0; margin: 0; padding: 0; 
  border: none; overflow: hidden;
}

svg {
  color: orange;
  stroke: red;
}

.purple {
  color: purple;
  stroke: black;
}
<svg class="defs-only" xmlns="http://www.w3.org/2000/svg" >
  <symbol id="shape" width="50" height="50" viewbox="0 0 50 50">
    <circle cx="25" cy="25" r="20" fill="currentColor" stroke="inherit" />
  </symbol>
</svg>

<svg xmlns:xlink="http://www.w3.org/1999/xlink">
   <use xlink:href="#shape" x="10" y="10" />
   <use xlink:href="#shape" x="80" y="10" class="purple" />
</svg>

如果你要引用外部文件,你需要在 # 之前放置文件名,例如 image.svg#shape ,当然你需要确保路径是正确的。

请注意,不是所有的浏览器都支持片段标识符 - 特别是IE和Edge - 你需要在这些浏览器中使用像svg4everybody这样的javascript polyfill。

解决办法 - 只使用svg内联


当我尝试在同一文件中使用<use>,但将该文件作为HTML文件中的<img>加载时,xmlns:xlink非常关键。如果没有它,它将无法呈现。 - jdunning
注意 - xmlns:xlink 在 SVG 2.0 中已经过时...请参阅 https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/href 了解更多详情。 - Ruskin

3

您需要在带有所需形状的 SVG 内使用 use 标签:

<svg>
    <defs>
        <g id="shape">
            <circle cx="100" cy="100" r="100" />
        </g>
    </defs>

    <use xlink:href="#shape" x="10" y="10" />
</svg>

2
我认为在同一文档中使用两个SVG也可以:https://jsfiddle.net/t31vgbaj/ - pawel
那么如果我把这段代码放在image.svg中,并使用<img src="image.svg">加载它,它应该可以工作吗? - BarbuDorel
@lonesomeday 这意味着这个答案不仅事实上是错误的,而且回答了一个不同的问题。 - pawel
@BarbuDorel 不,图像是自包含的,不能有外部引用。它们也不能作为其他内容的引用。 - Robert Longson
1
现在应该使用href属性而不是xlink:href。请阅读有关mozilla.org - xlink:href的更多信息。 - mikaelwallgren
参考资料指出,如果没有提供ID,则应该采用根元素。 - vintprox

0

SVG 2(在浏览器中实现时)将允许引用另一个SVG文件,而无需任何片段标识符

SVG 2的新功能:没有片段的href允许引用整个SVG文档,而无需确保其根元素具有ID。

之前(SVG 1.1):

<!-- my-vector.svg -->

<svg id="icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
  <circle r="10" cx="12" cy="12" />
</svg>

<use href="my-vector.svg#icon"></use>

之后(svg 上将不需要定义 id="..."):

<!-- my-vector.svg -->

<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
  <circle r="10" cx="12" cy="12" />
</svg>

<use href="my-vector.svg"></use>

SVG 2似乎正在主要浏览器中开发过程中(请参见{{link1:此Chrome功能}}和特别是此Chromium问题:{{link2:Issue 366545:[SVG2]允许引用整个文件}})。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接