SVG填充未应用于FireFox [英] SVG Fill not being applied in FireFox

查看:126
本文介绍了SVG填充未应用于FireFox的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎无法找出为什么Firefox使用默认的svg填充颜色而不是类的填充。



这里是查看FF时的3个填充检查员:





正在通过

插入SVG。

 < svg class =icon> 
< use xmlns:xlink =http://www.w3.org/1999/xlinkxlink:href =#menu-bag>< / use>
< / svg>

应该显示.skip-link .icon填充白色(#fff)使用#002649的SVG填充;如果我将.skip-link .icon改为.skip-link svg,那么它工作正常。为什么我不能使用类,而是显式地声明元素



我缺少一些关于Firefox如何填充SVG的东西?

解决方案

如果Firefox的行为是唯一的,那么可能是因为#menu-bag 是指< symbol> 元素。



规格表示重新使用的< symbol> 应该被实现,如同它被嵌套< svg> / a>。 Firefox在它们的影子DOM中处理这个字面。



这意味着这个代码:

 < a href =#class =skip-link> 
< svg class =icon>
< use xmlns:xlink =http://www.w3.org/1999/xlinkxlink:href =#menu-bag>< / use>
< / svg>
< / a>

实现方式如下:

 < a href =#class =skip-link> 
< svg class =icon>
< use xmlns:xlink =http://www.w3.org/1999/xlinkxlink:href =#menu-bag>
<! - 开始的阴影DOM边界 - >
< svg><! - replacement for< symbol> - >
<! - graphics content - >
< / svg>
<! - 阴影DOM边界结束 - >
< / 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检查器隐藏。 / p>

这是一个原始问题的工作示例。也就是说,在Chrome,Safari,Opera或IE上,您会看到一个绿色的圆圈,当您将鼠标悬停在它不会改变,但在Firefox上,你会看到一个蓝色的圆圈,在悬停/焦点上变红。



  svg {fill:navy;} a:hover svg,a:focus svg {fill :red;}。skip-link .icon {fill:green;}。icon {height:50; width:50;}  

 < a href = class =skip-link> < svg class =icon> < use xmlns:xlink =http://www.w3.org/1999/xlinkxlink:href =#menu-bag/> < / svg>< / a>< svg height =0width =0> < symbol id =menu-bagviewBox = -  10 -10 20 20> < circle r =10/> < / symbol>< / svg>  



你修复它?您有两个选项,其中一个已经通过尝试和错误找出:


  1. 避免使用 svg 标签选择器,并依赖于< use> 元素的正常样式继承。


  2. 使用在Firefox中有意选择阴影 - < svg> 的选择器可取消默认值


一个选择是使用规则像下面这样,这将保持原始规则对其他浏览器的特殊性,同时也在Firefox上工作:

  .skip-link .icon,.skip-link .icon use> svg {
fill:green;
}

use> svg 选择器永远不会与 Firefox错误之外的任何匹配 >,所以它是安全使用没有副作用。 (最初,我只是建议在选择器的末尾添加 svg ,但在某些情况下可能会出现问题。)


I can't seem to figure out why Firefox is using the default svg fill color instead of the class's fill.

Here are the 3 fills when viewing the FF inspector:

SVG is being inserted via

<svg class="icon">
    <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#menu-bag"></use>
</svg>

It should be showing the .skip-link .icon fill of white (#fff) but it's actually using the SVG fill of #002649; If i change .skip-link .icon to .skip-link svg then it works fine. Why can I not use a class and instead but explicitly state the element??

Am I missing something obvious about how Firefox fills an SVG? This CSS works fine in other browsers.

解决方案

If the behavior is unique to Firefox, it is probably because #menu-bag refers to a <symbol> element.

The specs say that a re-used <symbol> should be implemented as if it were replaced by a nested <svg>. Firefox treats this literally in their shadow DOM. The shadow DOM isn't visible in your DOM inspector, but it is subject to CSS selectors.

Which means that this code:

<a href="#" class="skip-link">
    <svg class="icon">
        <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#menu-bag"></use>
    </svg>
</a>

Is implemented like this:

<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>

The svg.icon matches your .skip-link .icon rule (and as Kyle Mitt points out, that rule will always take precedence over your a:hover svg rule). This value is also inherited by the <use> element.

However, the shadow-DOM <svg> doesn't get the inherited value, because it is styled directly with the svg rule. When you change your selector to .skip-link svg, or when you trigger the a:hover svg rule, then the hidden inner element gets the style directly applied because that SVG is also a descendent of the link.

As Robert Longson noted in the comments, this is not how it is supposed to work. It's a side effect of the way that Firefox implements <use> elements as complete cloned DOM trees, which just happen to be hidden from your DOM inspector.

Here's a "working" example of your original problem. Which is to say, on Chrome, Safari, Opera, or IE you will see a green circle that isn't altered when you hover it, but on Firefox you will see a blue circle that turns red on hover/focus.

svg {
    fill: navy;
}
a:hover svg, a:focus svg {
    fill: red;
}
.skip-link .icon {
    fill: green;
}
.icon {
    height: 50;
    width: 50;
}

 <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>

So how do you fix it? You have two options, one of which you've already figured out by trial and error:

  1. Avoid setting default styles using the svg tag selector, and rely on normal style inheritance from the <use> element.

  2. Use selectors that intentionally select the shadow-<svg> in Firefox to cancel out the defaults, while also making sure that they have the intended effect on other browsers.

One option would be to use a rule like the following, which would maintain the specificity of your original rule for other browsers while also working on Firefox:

.skip-link .icon, .skip-link .icon use>svg {
    fill: green;
}

The use>svg selector will never match anything except with the Firefox bug, so it is safe to use without side effects. (Originally, I'd just suggested adding svg to the end of the selector, but that could be problematic in certain situations.)

这篇关于SVG填充未应用于FireFox的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆