SVG with 'svg' element embedded

Viewed 128

I've a problem with a complicated SVG image.

It works on Chrome and Firefox, but there is no way to convert it into a PNG image even using an online tool or GIMP and also with Inkscape.

I'm not sure where the problem is. Maybe because is it an image built with two other SVG images embedded.

Here is the SVG file.

To reproduce the problem: open the SVG file linked with a browser: it works.

Open it with GIMP and the image is empty.

An easier example with the same problem:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
  <!-- Some graphical objects to use -->
  <defs>
      <svg id="pippo" viewBox="0 0 10 10" >
      <circle id="myCircle" cx="5" cy="5" r="5" />
    </svg>

    <linearGradient id="myGradient" gradientTransform="rotate(90)">
      <stop offset="20%" stop-color="gold" />
      <stop offset="90%" stop-color="red" />
    </linearGradient>
  </defs>

  <!-- Using my graphical objects -->

  <rect height="100%" width="100%" fill="#fc0" />

  <use x="0" y="0" href="#pippo" fill="url('#myGradient')" />
</svg>

2 Answers

With SVG 1 you need to use the attribute xlink:href instead of href on the use element

<use x="0" y="0" xlink:href="#pippo" fill="url('#myGradient')" />

You will also need the xlink namespace on the <svg> element

<svg 
  viewBox="0 0 10 10" 
  xmlns="http://www.w3.org/2000/svg" 
  xmlns:xlink="http://www.w3.org/1999/xlink"
>

Since SVG 2, xlink: prefix is deprecated but SVG 2 is a W3C Candidate Recommendation and all its features are not yet supported by all browsers and editors.

Full SVG 1 example:

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <!-- Some graphical objects to use -->
  <defs>
    <svg id="pippo" viewBox="0 0 10 10">
      <circle id="myCircle" cx="5" cy="5" r="5" />
    </svg>

    <linearGradient id="myGradient" gradientTransform="rotate(90)">
      <stop offset="20%" stop-color="gold" />
      <stop offset="90%" stop-color="red" />
    </linearGradient>
  </defs>

  <!-- using my graphical objects -->
  <rect height="100%" width="100%" fill="#fc0" />
  <use x="0" y="0" xlink:href="#pippo" fill="url('#myGradient')" />
</svg>

Workaround: SVG to PDF via the native browser feature "save to PDF" (print modal)

Since Firefox, Chromium, and WebKit have powerful built-in PDF export functionalities combined with way better SVG support than any "desktop" application, we can convert complex SVG images to a flattened, 'visually hardwired' vector file.

Ideal result

  • all vector data is retained (can also be opened in a vector application like Inkscape, Adobe Illustrator, Figma, etc.)
  • complexities like nested SVG images or <use> elements as well as transforms are repositioned to hardcoded vector x/y coordinates.

... but curb your enthusiasm: common issues

  • patterns and some complex gradients might be rasterized
  • you will lose structural data like layers, IDs and other editable features.

Manual SVG export optimisations

  • as @Yukulélé already pointed out: some syntax conventions and newer attributes might be too progressive
  • try to replace CSS-based styling with attributes – svgomg can be helpful
  • reusable elements defined in <defs> or as <symbols> might have quirky recursive dependencies
  • try to clean up unnecessary or invalid properties (e.g., hexadecimal RGBA) and fix incomplete SVG nestings (missing end tags)
  • document dimensions and aspect ratios can often be better retained (by a graphic application), when the parent SVG element was added a viewBox and width/height attributes (at least in Adobe Illustrator)
Related