Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is style not applied to svg element in Firefox?

I want to apply a CSS style to an SVG element that's inside a SVG <defs> element. While in Chrome and Internet Exporer (version 11) the following code works fine, in Firefox it doesn't. How can I apply the style to the SVG element inside the defs also in Firefox ?

#symbolcontainer.green #mysymbol { fill: green; }
<svg>
    <g id="symbolcontainer" class="green">
        <defs>
            <g id='mysymbol'>
                <defs>
                    <circle id="myCircle" r="2" cx="2" cy="2"/>
                </defs>
                <use href="#myCircle"/>
            </g>
        </defs>
        <use href="#mysymbol" />
    </g>
</svg>

While in chrome and Internet Explorer the circle is green (style is applied) in Firefox it's black (style not applied).

See and test with this fiddle.

I've searched at stackoverflow for "svg firefox style defs" but didn't find an answer to my question.

like image 853
Stonecrusher Avatar asked Jan 21 '18 13:01

Stonecrusher


People also ask

Can we add style to SVG?

The SVG <style> element allows style sheets to be embedded directly within SVG content. Note: SVG's style element has the same attributes as the corresponding element in HTML (see HTML's <style> element).

Does CSS support SVG?

We can use SVG in CSS via data URI, but without encoding it works only in Webkit based browsers. If encode SVG using encodeURIComponent() it will work everywhere. SVG must have attribute xmlns like this: xmlns='http: //www.w3.org/2000/svg' .

What is a SVG class?

class - SVG: Scalable Vector Graphics | MDN.


1 Answers

In SVG 2 styles are not applied if they cross the shadow-element boundary.

The shadow tree is created by <use> elements and consists of the "shadows" of the elements (and their children) that the <use> element points to.

In other words if you have a complex selector (one that contains 2 or more elements) and one of those elements selects from the main document while the other selects within the use element's children, it is not going to be applied.

Let's look at your selector.

  • symbolcontainer is in the main document
  • mysymbol is in the shadow tree, it's cloned into the <use> element.

So that selector should do nothing in an SVG 2 compliant implementation.

If you want a style to apply simply set the selector to one or the other part so it does not cross the boundary. E.g.

#symbolcontainer.green { fill: green; }
<svg viewBox="0 0 5 5">
    <g id="symbolcontainer" class="green">
        <defs>
            <g id='mysymbol'>
                <defs>
                    <circle id="myCircle" r="2" cx="2" cy="2"/>
                </defs>
                <use href="#myCircle"/>
            </g>
        </defs>
        <use href="#mysymbol" />
    </g>
</svg>

Firefox implements this part of the SVG 2 specification, other browsers will likely catch up and implement it too at some point.

like image 149
Robert Longson Avatar answered Oct 07 '22 02:10

Robert Longson