Search code examples
javascriptsvgfirefoxfirefox-addonfirefox-addon-webextensions

How do I set my SVG icons' background to be transparent?


Update:

My interpretation of the problem was incorrect. Rather than the background turning black, the stroke was being scaled incorrectly. It just appeared to have a black background. I have reported the bug to Bugzilla

Original Question:


I have a Firefox extension that has a browser action and a context menu item with custom icons (the same icon). I have been using PNG images for the icons, but I want to switch to SVG icons. The only problem with SVG icons is that Firefox fills in the background with black, rather than keeping it transparent. I have checked the icon's transparency by opening it with several apps, all of which naturally give the SVG a transparent background. Why does Firefox not recognize its transparency when I use it as an extension's context menu item's icon or a browser action's icon?

Here is a snippet with proof that the icon is transparent:

body {
  background-color: red;
  animation-name: changeColors;
  animation-duration: 1s;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}

@keyframes changeColors {
  from {
    background-color: red;
  }
  to {
    background-color: green;
  }
}
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketchjs="https://sketch.io/dtd/" sketchjs:metadata="eyJuYW1lIjoiRHJhd2luZyIsInN1cmZhY2UiOnsiaXNQYWludCI6dHJ1ZSwibWV0aG9kIjoiZmlsbCIsImJsZW5kIjoibm9ybWFsIiwiZW5hYmxlZCI6dHJ1ZSwib3BhY2l0eSI6MSwidHlwZSI6InBhdHRlcm4iLCJwYXR0ZXJuIjp7InR5cGUiOiJwYXR0ZXJuIiwicmVmbGVjdCI6Im5vLXJlZmxlY3QiLCJyZXBlYXQiOiJyZXBlYXQiLCJzbW9vdGhpbmciOmZhbHNlLCJzcmMiOiJ0cmFuc3BhcmVudExpZ2h0Iiwic3giOjEsInN5IjoxLCJ4MCI6MC41LCJ4MSI6MSwieTAiOjAuNSwieTEiOjF9LCJpc0ZpbGwiOnRydWV9LCJjbGlwUGF0aCI6eyJlbmFibGVkIjp0cnVlLCJzdHlsZSI6eyJzdHJva2VTdHlsZSI6ImJsYWNrIiwibGluZVdpZHRoIjoxfX0sImRlc2NyaXB0aW9uIjoiTWFkZSB3aXRoIFNrZXRjaHBhZCIsIm1ldGFkYXRhIjp7fSwiZXhwb3J0RFBJIjo3MiwiZXhwb3J0Rm9ybWF0IjoicG5nIiwiZXhwb3J0UXVhbGl0eSI6MC45NSwidW5pdHMiOiJweCIsIndpZHRoIjoxMjgsImhlaWdodCI6MTI4LCJwYWdlcyI6W3sid2lkdGgiOjEyOCwiaGVpZ2h0IjoxMjh9XSwidXVpZCI6Ijg4OWIxNzZlLWJlOTEtNGNlYS1hZTRjLWY5MGVhNWI0YzFiYiJ9" width="128" height="128" viewBox="0 0 128 128">
  <path style="fill: #242529; stroke: #121212; mix-blend-mode: source-over; paint-order: stroke fill markers; fill-opacity: 1; stroke-dasharray: none; stroke-dashoffset: 0; stroke-linecap: round; stroke-linejoin: miter; stroke-miterlimit: 4; stroke-opacity: 0.7; stroke-width: 15; vector-effect: non-scaling-stroke;" sketchjs:tool="circle" d="M50 0 C77.614 0 100 22.386 100 50 100 77.614 77.614 100 50 100 22.386 100 0 77.614 0 50 0 22.386 22.386 0 50 0 z" transform="matrix(1.0804830483049923,0,0,1.0804830483049923,10.000000000200153,10.332170735958027)"/>
  <path style="fill: #242529; stroke: #121212; mix-blend-mode: source-over; paint-order: stroke fill markers; fill-opacity: 1; stroke-dasharray: none; stroke-dashoffset: 0; stroke-linecap: round; stroke-linejoin: miter; stroke-miterlimit: 4; stroke-opacity: 0.6666666666666667; stroke-width: 20; vector-effect: non-scaling-stroke;" sketchjs:tool="circle" d="M50 0 C77.614 0 100 22.386 100 50 100 77.614 77.614 100 50 100 22.386 100 0 77.614 0 50 0 22.386 22.386 0 50 0 z" transform="matrix(1.0804830483049923,0,0,1.0804830483049923,10.000000000200153,10.000000000199847)"/>
  <path style="fill: #999999; mix-blend-mode: source-over; fill-opacity: 1;" sketchjs:tool="path" d="M0 75.09 C75.48 68.13 71.72 0 71.72 0 71.72 0 105.68 98.51 1.17 75.85 " transform="matrix(0.8743546320957299,0,0,0.8743546320957296,40.281708922438206,37.527195340009996)"/>
  <path style="fill: #ffe067; mix-blend-mode: source-over; fill-opacity: 1; vector-effect: non-scaling-stroke;" sketchjs:tool="star" d="M12.249 0 L15.848 7.294 23.898 8.464 18.073 14.141 19.448 22.158 12.249 18.373 5.049 22.158 6.424 14.141 0.599 8.464 8.649 7.294 z" transform="matrix(0.697355799061732,-0.13642022494671896,0.13642022494671896,0.697355799061732,41.265182438537245,79.6845481140266)"/>
  <path style="fill: #ffe067; mix-blend-mode: source-over; fill-opacity: 1; vector-effect: non-scaling-stroke;" sketchjs:tool="star" d="M9.084 0 L11.754 5.41 17.724 6.277 13.404 10.488 14.424 16.434 9.084 13.626 3.745 16.434 4.764 10.488 0.445 6.277 6.414 5.41 z" transform="matrix(0.9902159962126372,0.13954311464423616,-0.13954311464423616,0.9902159962126372,20.83972994628792,35.244013452720175)"/>
  <path style="fill: #ffe067; mix-blend-mode: source-over; fill-opacity: 1; vector-effect: non-scaling-stroke;" sketchjs:tool="star" d="M12.182 0 L15.762 7.254 23.768 8.418 17.975 14.064 19.343 22.038 12.182 18.273 5.022 22.038 6.389 14.064 0.596 8.418 8.602 7.254 z" transform="matrix(0.9975510002532796,0.06994284733753305,-0.06994284733753305,0.9975510002532796,77.22221836207314,21.377447387233143)"/>
</svg>

Here are screenshots of the icon not being transparent:

opaque icon on toolbaropaque icon in context menu

I am also changing the icon using browser.browserAction.setIcon() in the background page, but that shouldn't affect anything.


Solution

  • Update:

    Turns out I misunderstood the idea of a "non-scaling-stroke." The stroke was just being scaled up and I misunderstood the stroke for an opaque background.

    Original Answer:


    I've found the culprit: vector-effect: non-scaling-stroke; in the style. While it's a nice effect, it isn't important enough to create an opaque background. I wonder why Firefox gives the icon an opaque background when that effect is included... Perhaps we will be able to use later if Mozilla wants to fix it.