我似乎无法弄清楚为什么Firefox使用默认的svg填充颜色而不是类的填充。
以下是查看FF检查员时的3次填充:
正在通过
插入SVG<svg class="icon">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#menu-bag"></use>
</svg>
它应该显示.skip-link .icon填充白色(#fff),但它实际上是使用#002649的SVG填充;如果我将.skip-link .icon更改为.skip-link svg,那么它可以正常工作。为什么我不能使用类而是显式地声明元素??
我是否遗漏了一些关于Firefox如何填充SVG的明显内容?这个CSS在其他浏览器中运行良好。
答案 0 :(得分:37)
如果该行为在版本56之前是Firefox独有的,那是因为#menu-bag
引用了<symbol>
元素。
规格说重新使用<symbol>
should be implemented as if it were replaced by a nested <svg>
。 Firefox过去常常在他们的影子DOM中对待它。阴影DOM在DOM检查器中不可见,但它受CSS选择器的限制。
这意味着这段代码:
<a href="#" class="skip-link">
<svg class="icon">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#menu-bag"></use>
</svg>
</a>
WAs的实施方式如下:
<a href="#" class="skip-link">
<svg class="icon">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#menu-bag">
<!--Start of shadow DOM boundary-->
<svg><!-- replacement for <symbol> -->
<!-- graphics content -->
</svg>
<!--End of shadow DOM boundary-->
</use>
</svg>
</a>
svg.icon
符合您的.skip-link .icon
规则(正如Kyle Mitt指出的那样,该规则始终优先于您的a:hover svg
规则)。此值也由<use>
元素继承。
然而,shadow-DOM <svg>
没有获得继承的值,因为它直接使用svg
规则设置样式。当您将选择器更改为.skip-link svg
或触发a:hover svg
规则时,隐藏的内部元素将直接应用样式,因为该SVG也是链接的后代。
正如Robert Longson在评论中指出的那样,假设的工作原理并非如此。这是Firefox将<use>
元素实现为完整克隆DOM树的方式的副作用,这些DOM树恰好隐藏在DOM检查器中。
这是&#34;工作&#34;原始问题的例子。也就是说,在Chrome,Safari,Opera,Firefox 56+或IE上,您会看到一个绿色圆圈,当您将其悬停时,它不会被改变,但在版本56之前的Firefox上,您将看到一个蓝色圆圈悬停/焦点时红色。
svg {
fill: navy;
}
a:hover svg, a:focus svg {
fill: red;
}
.skip-link .icon {
fill: green;
}
.icon {
height: 50;
width: 50;
}
&#13;
<a href="#" class="skip-link">
<svg class="icon">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#menu-bag" />
</svg>
</a>
<svg height="0" width="0">
<symbol id="menu-bag" viewBox="-10 -10 20 20">
<circle r="10" />
</symbol>
</svg>
&#13;
那么如果您需要支持旧版本的Firefox,该怎么做?您有两种选择,其中一种已经通过反复试验找出:
避免使用svg
标记选择器设置默认样式,并依赖<use>
元素的正常样式继承。
使用有意选择阴影的选择器 - <svg>
来取消默认值,同时确保它们在其他浏览器上具有预期效果。
一种选择是使用如下规则,这将保持原始规则对其他浏览器的特异性:
.skip-link .icon, .skip-link .icon use>svg {
fill: green;
}
use>svg
选择器永远不会将除以外的任何内容与Firefox bug匹配,因此使用时没有副作用是安全的。 (最初,我只是建议在选择器的末尾添加svg
,但在某些情况下这可能会有问题。)
答案 1 :(得分:3)
基于@AmeliaBR提供的答案,更通用的选择是简单地做一些事情:
svg use svg {
fill: inherit;
}
将使阴影元素继承填充颜色。
答案 2 :(得分:2)
罗伯特是正确的,<use>
并不总是一致地应用。当然,当您将SVG用作图像时,它不知道如何应用您已添加到页面中的任何CSS规则。
但是这里还有很多其他的东西可以决定元素的风格,所以一个例子可能会有所帮助。
这是一个用于讨论的堆栈片段。
svg {
fill: blue;
}
a:hover svg {
fill: red;
}
.skip-link .icon {
fill: purple;
}
.green {
fill: green;
}
&#13;
<a href="#" class="skip-link">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
class="icon" >
<def>
<text id="text" >use xlink</text>
<text id="over" class="green">use xlink override</text>
</def>
<text x="5" y="15" >Plain</text>
<use x="5" y="30" xlink:href="#text" />
<use x="5" y="50" xlink:href="#over" />
<text x="5" y="65" class="green" >class="green"</text>
<text x="5" y="80" fill="orange" >fill="orange"</text>
</svg>
</a>
&#13;
SVG元素本身的样式有几个相互冲突的规则。决定哪条规则获胜的因素与[特异性和顺序]有关。在这种情况下,SVG元素本身将以紫色结束。例如,悬停锚定规则将永远不会显示,因为它的特定性不如.skip-link .icon
某些属性允许从父级继承,但仅限于未指定的属性。任何规范都将覆盖继承的值。如果问题是,我的<svg>
元素具有某种风格,为什么它不能同等地应用于所有子元素,答案很简单。对于子元素来说,指定自己的值并覆盖继承的值是完全正确的。
<text x="5" y="65" style="fill:green;" >class="green"</text>
<text x="5" y="80" fill="orange" >fill="orange"</text>
棘手的部分成为涉及使用时发生的事情。在这种情况下,可能很难跟踪正在应用的实际样式。使用将创建由xlink
属性标识的元素的内联表示,但您无法直接访问此元素。因此,在开发人员工具中选择use
只会显示应用于元素父级的样式。元素本身可能会覆盖继承的属性,我们无法在开发面板中观察它。
例如,这里应用的样式是从父级继承的。在开发人员工具中,似乎获胜规则是紫色的,但这只是因为它没有考虑被拉入的元素。这是一个可以被覆盖的 soft 值如果元素指定任何值。
但是内联文本的完整选择器实际上看起来像这样:
我将来建议的一件事是提供可运行代码,其他人可以使用它来轻松重现问题,因为它可以节省大量额外的调试时间。但是,我怀疑你的确切情况正在发生:
svg {
fill: #002649;
}
a:hover svg {
fill: #8A8B8C;
}
.skip-link .icon {
fill: #FFF;
}
&#13;
<a href="#" class="skip-link">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
class="icon" >
<def>
<svg xmlns="http://www.w3.org/2000/svg" id="menu-bag">
<rect height="100" width="100" />
</svg>
</def>
<use xlink:href="#menu-bag" />
</svg>
</a>
&#13;
答案 3 :(得分:1)
在body或html标记上设置默认的svg填充颜色,它将作为默认值继承,但您只需使用类就可以轻松覆盖它。
body {
fill: black;
}
.green {
fill: green;
}
.red {
fill: red;
}
现在只需在任何地方使用颜色类来更改填充颜色。将颜色类添加到svg,或包含svg的span或其他元素。也适用于Firefox。
<a href="#" class="skip-link green">
<svg>
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#menu-bag" />
</svg>
</a>
<svg height="0" width="0">
<symbol id="menu-bag" viewBox="-10 -10 20 20">
<circle r="10" />
</symbol>
</svg>
答案 4 :(得分:0)
我的情况并不完全相同,但我还是同意。 我正在使用svg作为背景图像,如下面的示例(用谷歌搜索,不记得在哪里)。并且在Firefox中,“填充”颜色存在问题。
如果我写例如“ fill:blue;”它也会正确显示。
.a-class {
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 10' preserveAspectRatio='none' height='130' style='background:var(--main-lt-green); fill:rgb(237, 237, 237);'><polygon points='100 0 100 10 0 10'></polygon></svg>");
background-repeat: no-repeat;
background-size: 100% 100px;
background-position-y: top;
margin-top: -100px;
padding-top: 100px;
}