SVG使用和渐变作为填充

48
我一直在尝试将我的SVG图标外部化到一个文件中,并使用类似于<svg><use xlink:href="file.svg#icon" /></svg>的标记引用它们。理论上,这个方法非常好,但是不同的浏览器在渲染时会出现问题。当在文件内使用<use>引用符号并直接打开SVG文件的URL时,所有浏览器都可以正确地渲染SVG。
简而言之,在标记中使用<svg><use/></svg>引用符号时,是否有跨浏览器的方法来使SVG linearGradient作为元素填充工作?
我设置了一个演示问题的plunker: http://plnkr.co/edit/feKvZ7?p=preview 简化后的标记如下:

<!DOCTYPE html>
    <html>
      <body>
        <h1>SVG sprite test</h1>
        <svg width="100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
          <use xlink:href="icon.svg#icon" />
        </svg>
      </body>
    </html>

而SVG文件看起来像这样:

  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
      <defs>
        <linearGradient id="gradient">
          <stop offset="0" stop-color="black" />
          <stop offset="1" stop-color="white" />
        </linearGradient>
      </defs>
      <symbol id="icon" viewBox="0 0 100 100">
        <circle cx="50" cy="50" r="40" stroke="black" fill="url(#gradient)" />
      </symbol>
    
      <use id="iconuse" xlink:href="#icon" width="100" height="100" />
    
    </svg>

这是在不同浏览器中呈现线性渐变符号的不同结果: Different results of rendering linear gradients for symbols in different browser

3
多年以后了,你现在做什么? - Nick Darvey
3
@NickDarvey 一个好问题。我已经放弃使用这种方法,现在正在使用像 svgr 这样的工具:https://github.com/gregberge/svgr。不过现在可能是重新考虑的有趣时机。快速查看 Plunkr,不同浏览器渲染不同 SVG 的方式仍然存在差异。 - RJo
2个回答

1
symbol 标签用于隐藏其内部的元素。使用 <use> 命令按其唯一标识符调用 symbol 内部的元素。
因此,最好使用这种调用单个元素的方法,而不是调用整个 symbol

此外,使用 <use> 时,元素会进入 shadow DOM,在某些情况下使用 CSS 变得不可能。
因此,最好删除 symbol 中的所有内部样式,并将它们直接分配给 use 命令。

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <linearGradient id="gradient">
      <stop offset="0" stop-color="black" />
      <stop offset="1" stop-color="white" />
    </linearGradient>
  </defs>
  <symbol  id="icon"  viewBox="0 0 100 100"> 
    <circle id="circle" cx="50" cy="50" r="40"   />
     <rect id="rect" x="100" y="10" width="100" height="100" />
  </symbol>

  <use class="iconuse" xlink:href="#circle" width="100" height="100" fill="url(#gradient)" stroke="black" />
     <use class="iconuse" xlink:href="#rect" width="100" height="100" fill="url(#gradient)" />
</svg>


MDN显示在符号标记中直接使用xlink:href而不是其中的单个元素:https://developer.mozilla.org/en-US/docs/Web/SVG/Element/symbol - RJo
@RJo 在哪里说不能从Symbol调用单个元素?在MDN中只有一个内部元素的示例,而我有两个元素。如果你确定你所说的,请展示来自W3C规范的链接。 - Alexandr_TT
那只是指向您原始描述的方式:“最好使用此调用单个元素的方法,而不是调用整个符号”。无论如何,原始问题是关于指向外部SVG文件中具有ID的元素。而不是指向内联SVG定义中的元素。 - RJo

0

尝试下一个(这是Inkscape提供渐变实现的方式):

<linearGradient id="gradient">
  <stop
     style="stop-color:black;"
     offset="0"/>
  <stop
     style="stop-color:white;"
     offset="1" />
</linearGradient>
...
<path
   style="fill:url(#gradient); ...

将属性更改为“style”属性并不能解决问题。 - RJo
尝试将内联SVG更改为img <img src="./icon.svg#icon" /> - FieryCat
那可能适用于渲染,但我会失去多功能性。不想这么做。 - RJo
3
有进展吗?我遇到了同样的问题,无法解决。 - Bice

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