scratchblocks icon indicating copy to clipboard operation
scratchblocks copied to clipboard

SVG Styling breaks at import into vector graphic tools (solid black shapes)

Open milankarow opened this issue 2 years ago • 10 comments

I am trying to import scratchblock SVGs into different vector graphic tools but all tools I tried seem to have difficulties with interpreting the style definitions.

I tried it with Inkscape and Affinity Designer 2, as well as online tools like Figma. All these tool render the SVG completely black, hinting at problems with the style information.

I investigated by generating a minimal example (one block "x position").

When looking into the SVG file via text editor, there seem to be weird issues with spacing in the CDATA-sequence where the CSS definitions are generated. Unfortunately, I am not at all an expert on CSS class syntax, but to me it looked like some class names were broken. For instance in classnames with scratchblocks-style-scratch3-high-contrast .sb3 it looks like the space before .sb3 is causing issues?

btw: I am talking about the generator on the github.io page (v 3.6.4 apparently)

Thank you for any hints and/or for looking into this!

milankarow avatar Dec 14 '23 15:12 milankarow

I tested it in inkscape, and found out that it's because scratchblocks uses svg features that are not present in inkscape, or at least inkscape doesn't assume things as much as browsers do. Although I think I found what is wrong. In the styles, it has svg .sb3-{style}, which inkscape doesn't like having styles targeted inside the svg element (that's what the space after the svg represents). I also noticed that inkscape does not show colors that are not in the hex color code format, which isn't a problem here, but may be a problem in other projects (such as my fork, heh). Your best bet is to use some online svg editor (not scratch, scratch messes up the svg, it removes icons, and moves the text down a bit). The reason why an online svg editor might work better is because those rely on the browser to render the svg, whereas inkscape uses their own svg renderer.

It also might be worth mentioning that GIMP is able to import the svg correctly, the only problem is that GIMP is not an svg editor, so it converts it to bitmap.

If you are inclined to get it to work in inkscape, then you can go into the svg, and edit it manually to remove unused stuff, and fix what inkscape has problems with.

Here are the steps I took to doing this.

  1. Go to https://jakearchibald.github.io/svgomg/ and optimize the svg so it's easier to hand edit (and so it doesn't include unused stuff).
  • Remove unused defs
  • Turn off any rounding
  • Prettify markup (to make it easier to edit manually)
  • Minify styles (it only keeps the needed ones to make it easier to edit)
  • And generally what you feel like you can remove.
  1. Download the resulting svg, then open it in a text editor (preferable a code editor, like notepad++, one that has syntax highlighting to make it easier to find stuff).
  2. Find the <style> element, and then inside that, remove any svg . If you want to , you can also remove unused icons.
  3. Save the file, then open it in inkscape. You should see the correct block(s).

ego-lay-atman-bay avatar Jan 23 '24 02:01 ego-lay-atman-bay

Ooh, you're both right! Exporting the CSS styles as .sb3-… rather than svg .sb3… seems to make these graphic editors much happier with the styling of our SVGs. I don't see why we couldn't update our SVG export to do that automatically.

What I can't remember is whether we can remove this from all our CSS, or whether we'll need to have a separate version for SVG export and for display inside the HTML in a browser. @apple502j do you happen to have any thoughts on this?

tjvr avatar Jan 30 '24 08:01 tjvr

I've actually already removed the SVG selector in my fork, and I have not ran into any issues with it so far.

ego-lay-atman-bay avatar Jan 30 '24 08:01 ego-lay-atman-bay

Hey, thank you all for your comments and hints.

I managed to refactor the style information so that the vector tools would accept it. I removed the svg selector and did a few other things I cannot really document on, since it was all a bit trial and error (sorry for that).

One particular thing I additionally discovered, was that Affinity Designer specifically (I haven't tested Inkscape for this) also does not like comma separated class lists. So I split those up and gave them individual (identical) style information.

I also removed all the high-contrast styles since I could not get them to work via in the vector tools (they seem to ignore the svg element class property?).

milankarow avatar Jan 30 '24 08:01 milankarow

I think we have to avoid relying on the CSS cascade at all.

Moving the style class from the root svg element, to an inner g element -- like below -- is enough for Inkscape, but not for Figma.

screenshot_2024-04-15-132952

To get it working in Figma, I had to avoid relying on the CSS cascade at all.

I guess we need to refactor our CSS again, to:

  • Avoid relying on the CSS cascade (i.e. use totally separate classes for the Original and High Contrast styles)
  • Avoid comma-separated class lists

tjvr avatar Apr 15 '24 12:04 tjvr

I've actually started working on a block color system in snapblocks that doesn't rely on classes. It works by storing the colors in the js, and then just applying the color to the element. I don't know if it would be useful for this though.

ego-lay-atman-bay avatar Apr 15 '24 14:04 ego-lay-atman-bay

Interesting!

I don't think there's a problem with using CSS classes here. It's probably cleaner — and it should mean people can edit the colours in an editor, if they so wish, and have it apply to all blocks of that category.

I think we just need to be more careful in how we use them!

tjvr avatar Apr 16 '24 23:04 tjvr

That makes sense. I mean, snapblocks does a lot more with colors than scratchblocks, so classes should work just fine (I mean, they already do, so there's not really any reason to not use them).

ego-lay-atman-bay avatar Apr 16 '24 23:04 ego-lay-atman-bay