Search code examples
csssvgstylish

Stylish custom stylesheets do not work with SVG nodes


I found a strange issue and I'm not sure if it's a bug or normal behavior. Maybe I've got something wrong?

I am trying to make a custom Stylish stylesheet to style some SVG elements. The stylesheet:

svg circle {
  fill: #1E90FF;
  stroke-width: 5;
  stroke: black;
}

It should look like this (without the frame):

image description

The stylesheet refused to work when placed in Stylish but works when in the document. So I tried this as a snippet:

svg.A circle {
  fill: #1E90FF;
  stroke-width: 5;
  stroke: black;
}
<svg style="width: 100px" class="A" viewbox="0 0 70 70">
 <circle class="circle" cx="35" cy="35" r="30" />
</svg>
<svg style="width: 100px" class="B" viewbox="0 0 70 70">
 <circle class="circle" cx="35" cy="35" r="30" />
</svg>

<div id="testdiv">
This is a reference test div to test that your stylesheet is working.
</div>

And used this custom stylesheet via Stylish:

@namespace url(http://www.w3.org/1999/xhtml);

@-moz-document domain("stacksnippets.net") {
  #testdiv {
    color: green;
    background-color: yellow;
  }
  svg.B circle {
    fill: #1E90FF;
    stroke-width: 5;
    stroke: black;
  }
}

And what I see is this:

image description

I can't imagine why stylish would filter out the styles for CSS, that sounds like nonsense.


Solution

  • Update:
    Tomáš Zato's answer is correct.
    See the @namespace reference on MDN.

    You need to include the SVG namespace like so:

    @namespace url(http://www.w3.org/1999/xhtml); 
    @namespace url(http://www.w3.org/2000/svg);
    
    @-moz-document domain("stacksnippets.net") {
        #testdiv {
            color: green;
            background-color: yellow;
        }
        svg.B circle {
            fill: #1E90FF;
            stroke-width: 5;
            stroke: black;
        }
    }
    

    Stylish doesn't filter out styles (Inspect the source code).
    But it does inject them at the Chrome level above/outside/before the normal DOM. (That's the reason why Stylish can fix CSS without any of the annoying flicker that userscript-applied CSS sometimes has.)

    I'm just guessing, but maybe there's some kind of issue with Firefox about SVG and these kinds of "outside DOM" styles?
    Note that your style works perfectly fine in Chrome with the Chrome Stylish extension.

    An alternate approach is to inject the CSS into the DOM, like so, using a userscript:
    (Except in a Greasemonkey/Tampermonkey script, just use GM_addStyle().)

    function addStyle (cssStr) {
        var D               = document;
        var newNode         = D.createElement ('style');
        newNode.textContent = cssStr;
        var targ    = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
        targ.appendChild (newNode);
    }
    addStyle ( `
        #testdiv {
            color: red;
            background-color: yellow;
        }
        svg.B circle {
            fill: #1E90FF;
            stroke-width: 5;
            stroke: pink;
        }
    ` );
    svg.A circle {
        fill: #1E90FF;
        stroke-width: 5;
        stroke: black;
    }
    <svg style="width: 100px" class="A" viewbox="0 0 70 70">
        <circle class="circle" cx="35" cy="35" r="30" />
    </svg>
    <svg style="width: 100px" class="B" viewbox="0 0 70 70">
        <circle class="circle" cx="35" cy="35" r="30" />
    </svg>
    <div id="testdiv">
        This is a reference div to test if your stylesheet is otherwise working.
    </div>