SVG "fill: url(#....)" 在 Firefox 中表现异常

Posted

技术标签:

【中文标题】SVG "fill: url(#....)" 在 Firefox 中表现异常【英文标题】:SVG "fill: url(#....)" behaving strangely in Firefox 【发布时间】:2013-02-13 23:02:48 【问题描述】:

我有以下 SVG 图形:

<svg width='36' height='30'>
  <defs>
    <linearGradient id="normal-gradient" x1="0%" y1="0%" x2="0%" y2="100%">
      <stop offset="0%" style="stop-color:rgb(81,82,84); stop-opacity:.4"/>
      <stop offset="100%" style="stop-color:rgb(81,82,84); stop-opacity:1"/>
    </linearGradient>
    <linearGradient id="rollover-gradient" x1="0%" y1="0%" x2="0%" y2="100%">
      <stop offset="0%" style="stop-color:rgb(0,105,23); stop-opacity:.5"/>
      <stop offset="100%" style="stop-color:rgb(0,105,23); stop-opacity:1"/>
    </linearGradient>
    <linearGradient id="active-gradient" x1="0%" y1="0%" x2="0%" y2="100%">
      <stop offset="0%" style="stop-color:rgb(0,0,0); stop-opacity:.4"/>
      <stop offset="100%" style="stop-color:rgb(0,0,0); stop-opacity:1"/>
    </linearGradient>
  </defs>

  <text x="8" y="25" style="font-size: 29px;" font-family="Arial">hello world</text>
</svg>'

我通过 CSS 设置了text 元素的fill 属性,并根据悬停状态在各种渐变之间切换。这在 Chrome 和 Safari 中效果很好,但在 Firefox 中,文本不会显示。检查该元素后,我发现 Firefox 将 none 附加到我的 fill: url(#...) CSS 属性的末尾。我尝试使用 Firebug 删除 none 关键字,但 Firebug 只是删除了整个属性。为什么会这样?

编辑: 我应该注意,如果我删除设置fill 属性的CSS,并将fill 属性硬编码到text 元素中(而不是通过内联style 属性),则文本会在所有浏览器中正确显示。

【问题讨论】:

你的实际 CSS 是什么样的,与那个 SVG 搭配?至于“none”这个东西,“fill: url(whatever) none”和“fill: url(whatever)”是一回事;两者都说如果 url 上的东西不可用,就没有后备,不应该画任何东西。 @BorisZbarsky 谢谢,我没有意识到 'none' 指定了找不到第一个资源时会发生什么。 【参考方案1】:

想通了。在我的 CSS 中,我引用渐变的方式与我最初引用内联填充的方式相同:

#myselector 
    fill: url('#gradient-id');

要让它在 Firefox 中运行,我必须将其更改为:

#myselector 
    fill: url('/#gradient-id');

不知道为什么会这样。也许它与包含我的样式表的目录结构有关?

【讨论】:

样式表中的相对url() 相对于样式表进行解析。因此,如果您的样式表和 SVG 位于不同的目录中,那么您可能根本没有链接到 SVG。 Webkit 做不到这一点,我很确定 Boris 前段时间向他们的 bugtracker 报告了这一点。 嗨 Boris,我也遇到了这个问题,我看到你经常评论 Firefox 错误报告,你能解释一下为什么 fill: url("#gradient-id") 没有在 css 中指定时在 dom 中找到渐变 id,但是否内联?我没有将 svgs 加载到我的页面之外...... Chrome 的实现是否不正确?这似乎应该是预期的行为。 当像 style="fill: url(#gradient-id)" 这样放置内联时,url 按预期解析,但放在样式表中时却没有,这似乎表明这是一个错误,除非我缺少规范实现的细微差别 您的回答为我节省了大量时间。当渐变不会出现在 Firefox 上时,我把头发拉了出来!【参考方案2】:

当我们使用 css(外部和内部 css)分配以下代码时,SVG “fill: url(#…)”在 Firefox 中的行为很奇怪。

#myselector 
fill: url('#gradient-id');

解决方案

提供内联样式,这可以通过两种方式完成。静态或动态方式

动态方式

.attr('fill', 'url(#gradient-id)')

静态方式

fill="url(#gradient-id)" 

在静态中你必须把它放在 SVG html 中;

【讨论】:

谢谢。另一个接受的答案似乎只有在从根 url 查看 svg 时才能修复(反之亦然)。 样式属性也适用于 css 类不适用的地方。例如 ..【参考方案3】:

我对 SVG 中的 linearGradient 有同样的问题 - 仍然在 2017 年。我猜,问题是 Firefox 将 url('#gradient-id') 视为普通 URL 并应用了 &lt;base href=""/&gt; 元标记的规则。把它注释掉,然后检查。

【讨论】:

问题中没有基本标签。这个问题是关于解析 CSS 样式表中的 url。它是针对样式表本身(如 CSS 规范所说)还是使用该样式表的文档(如 Chrome 所做的那样)解析。 当然,它不是——我只是认为这可能是它无法正常工作的一个原因。就我而言,这是一个原因。它与样式表无关,而是放置 id 标签(此处为 gradient-id)的位置。由于某些原因,使用带有 base 元标记的相对路径 #gradient-id 破坏了某些东西,FF 在任何地方都找不到 gradient-id 标记。在我的情况下,它不适用于 html(在 svg 圆圈中)和具有相对路径的 css 或 js。当我删除 base 标记或在 js 中设置绝对路径(如 .attr('stroke', "url("+window.location.href+"#gradient-id)" 元标记也会影响 Safari @lukdur。那么,您对这个问题的解决方案是什么?设置绝对路径? @AlexanderBurakevych 是的。我知道这不是完美的解决方案,但效果很好。这里有 jQuery 示例:$(someCircle).attr('stroke', "url(" + window.location.href + "#gradientId)");

以上是关于SVG "fill: url(#....)" 在 Firefox 中表现异常的主要内容,如果未能解决你的问题,请参考以下文章

svg circle标签可以填充图像吗

外部样式表中带有 fill:url(#id) 样式的 Firefox SVG,内联样式很好

SVG 检测“填充:无”上的 Onclick 事件

svg修改图标颜色

svg修改图标颜色

svg中怎么让一个图形按我指定的圆心旋转?