Why Is Style Not Applied to Svg Element in Firefox

Why is style not applied to svg element in Firefox?

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>

Styles not applied to SVG element in firefox and IE

The issue appears to be caused by capitalizing the svg selector in CSS. Take the following code snippet for example, where using SVG does not work, but svg does.

Example:

.wrap-a > SVG {    background: blue;}.wrap-b > svg {    background: green;}
<a class="wrap-a">    <svg width="226" height="226"><circle cx="110" cy="107" r="80" stroke="black" stroke-width="5" fill="red" /></svg></a><a class="wrap-b">    <svg width="226" height="226"><circle cx="110" cy="107" r="80" stroke="black" stroke-width="5" fill="red" /></svg></a>

SVG not working in Firefox

Move your circle's cx/cy/r css styles to element attributes.

Styling of SVG circle doesn´t work in Firefox, browser removes radius property

Seems like you found an inconsistent implementation of the SVG 2.0 spec in Firefox. Or, maybe Firefox does not fully support SVG 2.0 yet. The specification states that:

Some styling properties can be specified not only in style sheets and ‘style’ attributes, but also in presentation attributes.

So, both style sheets and attributes should work.


The quick fix is to add r, cxand cy presentation attributes to your circle element (as suggested here):

<circle _ngcontent-c1="" class="progress" style="stroke-dasharray: 131.947; stroke-dashoffset: 32.987;" cx="50%" cy="50%" r="21" fill="transparent" ng-reflect-ng-style="[object Object]"></circle>

g element does not adapt to svg on Firefox

Attaining correct dimensions for <svg>s is always an interesting topic.

Anyway, I just searched for relevant dimension issues for SVGs and found this Firefox bug: https://bugzilla.mozilla.org/show_bug.cgi?id=874811

which in turn refers to W3C docs (via a comment) which clearly states the following:

If the element has no associated CSS layout box or if the CSS layout box is inline, return zero.

I'm not exactly sure how Chrome assigns the correct dimensions (have never debugged that) but Firefox follows the above rule.

Another major bug WITH A SIMILAR DIMENSIONS ISSUE was raised for Firefox for getBoundingClientRect which used to output 0 (same as clientHeight/clientWidth) but this was fixed:
https://bugzilla.mozilla.org/show_bug.cgi?id=530985

So, in order to fix your code/lib and make it work for Firefox, I've come up with simple approaches:

Approach 1:

As you're adding CSS width:100% and height:100% to <svg>'s parent, you can replace this.canvas.clientWidth with (this.canvas.clientWidth || this.canvas.parentNode.clientWidth) and this.canvas.clientHeight with (this.canvas.clientHeight || this.canvas.parentNode.clientHeight) in the updateMatrix method.

For example:

const totalArea = Math.abs((this.canvas.clientWidth || this.canvas.parentNode.clientWidth) * (this.canvas.clientHeight || this.canvas.parentNode.clientHeight));
const totalCenter = this.math.centerOfArea((this.canvas.clientWidth || this.canvas.parentNode.clientWidth), (this.canvas.clientHeight || this.canvas.parentNode.clientHeight));

or you could set them up as constants. Your choice. And I see there are just 2 lines - both in the updateMatrix method. This approach might mess up if svg has certain margins, borders etc.

Approach 2:

As I mentioned above the bug about getBoundingClientRect which is now fixed in Firefox, you can use it the following way:

For example,

const totalArea = Math.abs(this.canvas.getBoundingClientRect().width * this.canvas.getBoundingClientRect().height);
const totalCenter = this.math.centerOfArea(this.canvas.getBoundingClientRect().width, this.canvas.getBoundingClientRect().height);

or set them as constants. Again, your choice.

I tried both of the above approaches by overriding in the console and it seems to work fine.

Here's a fiddle to clear things up by console logging dimensions with different methods. Try different browsers:

https://jsfiddle.net/shashank2104/mfksxwgo/

A snippet:

$(function () {  var svg = document.getElementById('foo');    console.log( svg.clientWidth, svg.clientHeight);  console.log( svg.parentNode.clientWidth, svg.parentNode.clientHeight);  console.log( svg.getBoundingClientRect().width, svg.getBoundingClientRect().height);  console.log( svg.width.baseVal.value, svg.height.baseVal.value);});
div {   width: 200px;   height: 200px;   background: #00f; }
svg { width: 100%; height: 100%; background: #f00; }
<!DOCTYPE html><html><head><meta charset=utf-8 /><script src="https://code.jquery.com/jquery-3.2.1.js"></script>
</head><body> <div> <svg id="foo"></svg> </div></body></html>


Related Topics



Leave a reply



Submit