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 类不适用的地方。例如我对 SVG 中的 linearGradient
有同样的问题 - 仍然在 2017 年。我猜,问题是 Firefox 将 url('#gradient-id')
视为普通 URL 并应用了 <base href=""/>
元标记的规则。把它注释掉,然后检查。
【讨论】:
问题中没有基本标签。这个问题是关于解析 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)"$(someCircle).attr('stroke', "url(" + window.location.href + "#gradientId)");
以上是关于SVG "fill: url(#....)" 在 Firefox 中表现异常的主要内容,如果未能解决你的问题,请参考以下文章