Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SVGO strips styles #1077

Closed
ossinkine opened this issue Jan 20, 2019 · 12 comments · Fixed by #1832
Closed

SVGO strips styles #1077

ossinkine opened this issue Jan 20, 2019 · 12 comments · Fixed by #1832
Assignees

Comments

@ossinkine
Copy link

ossinkine commented Jan 20, 2019

svgs.zip

Before.svg contains styles for shapes but after SVGO processing it does not contain them anymore and also shapes do not contain according attributes.

@popbee
Copy link

popbee commented Apr 20, 2019

You can turn off the inline styles option to keep them. Worked with your example.
This tool does not work well with more complex CSS selectors when inlining styles.
Also I see the styles being stripped off (empty <style> block) only when both minify and inline are used together.

    <style>
      .svg_tournament.cls-1 {
        isolation: isolate;
      }

      .svg_tournament .cls-2 {
        opacity: 0.75;
        mix-blend-mode: multiply;
      }

      .svg_tournament .cls-3,
      .svg_tournament .svg_color {
        fill: none;
        stroke-linecap: round;
        stroke-linejoin: round;
        stroke-width: 1.8px;
      }

      .svg_tournament .cls-3 {
        stroke: #000;
      }

      .svg_tournament .svg_color {
        stroke: #e8ce3a;
      }
    </style>

@strarsis
Copy link
Contributor

@ossinkine, @popbee: Disabling the onlyMatchedOnce option seems to be a workaround around this issue.
Hm, the onlyMatchedOnce apparently has a bug that causes loss of styles,
the cls-3 class in your example input SVG matches multiple time, hence it is affected.

@cneeson
Copy link

cneeson commented Jun 5, 2019

Neither of these approaches worked for me unfortunately. I am using svgo in combination with rollup-plugin-react-svg to export React component library SVGs. No matter what I try, the styles property always resolves as an empty object. (apologies, had to upload each of them as txt files as js and svg weren't supported)

Test case:
before.txt
after.txt
rollup.config.txt

@strarsis
Copy link
Contributor

strarsis commented Jun 5, 2019

@cneeson: It is probable that the svgo options you set in webpack aren't passed to svgo.
Have you tried to disable some plugins or set some options and check whether this changes the output?

@cneeson
Copy link

cneeson commented Jun 5, 2019

@strarsis thanks for getting back. Think I have confirmed that the options aren't being passed to svgo, there are illustrator comments throughout the test SVG that are removed by svgo, even when I set the removeComments option to false.

@strarsis
Copy link
Contributor

strarsis commented Jun 5, 2019

@cneeson: So you have to find out what part of your webpack setup doesn't pass the options to svgo.

@strarsis
Copy link
Contributor

@ossinkine, @cneeson: Were you able to fix the issue?

@ossinkine
Copy link
Author

@strarsis No, we just slightly modified the svgs so that svgo processes them correctly.

@alexeychikk
Copy link

I've disabled inlineStyles and removeStyleElement but style element still gets stripped.

@strarsis
Copy link
Contributor

@alexeychikk: Are you sure that those plugins are really disabled?

@strarsis
Copy link
Contributor

strarsis commented Oct 10, 2020

Stripped down SVG for reproducing the issue:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 45.49 35.68">
  <defs>
    <style>
      .wrapper.cls-1 {
        isolation: isolate;
      }

      .wrapper .some-stroke {
        stroke: #e8ce3a;
      }
    </style>
  </defs>
  <g class="wrapper cls-1">
    <polyline class="some-stroke" points="22.75 22.2 8.43 7.18 13.4 1.9 32.09 1.9 37.06 7.18 22.75 22.2 17.9 10.27 17.96 7.18"/>
    <polyline class="some-stroke" points="22.75 22.2 27.38 10.27 27.38 7.18"/>
  </g>
</svg>

It only happens with classes that are used more than once, hence the issue with onlyMatchedOnce turned on,
with a wrapper element being selected in the SVG styles.

Edit: So the reason for this is that when a selector is inlined, the element class is also stripped, if configured to do so.
However, the element class can be important in other selectors that hadn't been inlined because they don't match more than once (which is the default). To mitigate this issue, for each element from which the classes should be stripped, all the left-over rules must be checked for traversing that element, and only when they don't traverse that element, the class can be safely stripped.
For now, I would try to use a loop that builds each selector rule, selector by selector and performs a match check on the element.

@SethFalco
Copy link
Member

Thanks for reporting the issue, and thanks to strarsis for investigating it.
This has been resolved. The fix will be released in v3.0.4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants