tanem / react-svg

:art: A React component that injects SVG into the DOM.

Home Page:https://npm.im/react-svg

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

<style>-tag inside SVG becomes a page-wide style

PjotrB opened this issue · comments

We have lots of SVGs, many are defined like this:

<svg .... ><defs><style>.cls-1{fill:red;}</style></defs><path class="cls-1" d=......... /></svg>

And others are like this:

<svg .... ><defs><style>.cls-1{fill:green;}</style></defs><path class="cls-1" d=......... /></svg>

Both variants use the same class name cls-1 internally, only with a different fill setting. We don't create or maintain the SVGs ourselves, they are supplied by a 3rd party and we see cls-1 in a lot of their files, but we've also seen cls-2.

Now the issue:
If ReactSVG renders such SVGs into the page, these <style> blocks also get injected and they become page-wide styles. As a result the last rendered SVG "wins" and it will define what cls-1 means for all SVGs that use it (in fact even for everything on the page).

So if we render a red SVG followed by a green one, both become green.
If we render a green SVG followed by a red one, both become red.
This happens with the current version of ReactSVG (15.1.15) as well as much older versions (11.2.x),

Of course we can change our SVGs, but it would be an ongoing job to do so, and this could happen to anyone using it.
The ideal solution would be if ReactSVG would randomize all CSS class names, so it would render something like this:

<svg .... ><defs><style>.cls-1-hivshufgiudhvis{fill:red;}</style></defs><path class="cls-1-hivshufgiudhvis" d=......... /></svg>
<svg .... ><defs><style>.cls-1-qwrisudbgkshdgt{fill:green;}</style></defs><path class="cls-1-qwrisudbgkshdgt" d=......... /></svg>

PS I have searched for techniques that would allow me to force a "local" scope for <style> elements, but I have not found any. If there is, I'd love to learn about it.

Hi @PjotrB.

I'd recommend looking into doing this optimisation as a build step rather than at runtime using ReactSVG. Have you tried optimising your SVGs using a tool like svgo?

It does a number of things out of the box for you, including moving styles from <style> elements to inline styles, which I think might solve your issue. If the experiment works out OK, that process could form part of the build pipeline for your app, meaning you don't have to manually modify the source files each time.

Keen to hear how you get on anyway 🙏

Closing as the issue has been inactive for a while, feel free to comment if you have any other q's though.