'Merging multiple SVG files into one

first of all I know that there are many similar questions like this, but none of them seem to do the trick for me. I'd like to know if there is any way to combine multiple svg files within one single file. Somewhat like this:

<svg id="background" ...>
   <svg id="first" ...>
       ...
   </svg>
   <svg id="second" ...>
       ...
   </svg>
   ...
</svg>

Is there some sort of template or tutorial that helps me do this? In the end I want to do this programmatically using java und javafx 2.2.

svg


Solution 1:[1]

To change the SVG in exactly that way, you should check out my SVG Stacking Tool. As SVGs are XML one can use XSLT to transform the data:

Update: As pointed out in the comments, there seems to be a bug so that the SVG file is requested multiple times. More details and a possible solution can be found here:

Solution 2:[2]

You may try svg-join for combine multiple SVG in one symbol collection.

This tool create two files for you. The first is "svg-bundle.svg":

<svg ...>
  <symbol id="svg1" ...>
  <symbol id="svg2" ...>
</svg>

Every symbol is your separate SVG file.

The last one is "svg-bundle.css":

.svg_svg1,
.svg_svg2 {
  width: 20px; // for example
  height: 20px;
}

Now you may use it in your html:

<link rel="stylesheet" type="text/css" href="svg-bundle.css" />
...
<svg class="svg_svg1"><use xlink:href="svg-bundle.svg#svg1"></svg>
<svg class="svg_svg2"><use xlink:href="svg-bundle.svg#svg2"></svg>

Solution 3:[3]

I think the best and easiest way is to do this, assuming you only need to support the latest two major versions of major browsers, Android 9 Chrome, iOS 13 Safari, Desktop: Chrome, Firefox, Safari, Edge 87.

1 EDIT: First compress all the SVGs as they might break inside CSS otherwise using for example https://jakearchibald.github.io/svgomg/

2 Create a separate stylesheet and embed the svgs:

.icon-1 {
  background-image: url('data:image/svg+xml;utf8,<svg>...</svg>');
}
.icon-2 {
  background-image: url('data:image/svg+xml;utf8,<svg>...</svg>');
}

3 Lazy load this stylesheet with js - since these sorts of stylesheets tends to become very big and usually aren't needed to block rendering of the page.

I escaped # with %23(do not know if it's really necessary) it seems like you do not need to escape regular svgs in other ways - haven't tested if they contain inline style tags though (these styles can be moved to your stylesheet anyway)

Solution 4:[4]

After searching a lot of resource, I fount there is a python solution which is really handy: https://github.com/astraw/svg_stack

Say you have two svg file in hand, 11.svg 12.svg, what you can do is:

python svg_stack.py --direction=h --margin=100 11.svg 12.svg > 1.svg

You may think to have 6 svg files to lay out in this way:

11 12
21 22
31 32

which you can do following step:

# merge 11 12
python svg_stack.py --direction=h --margin=100 11.svg 12.svg > 1.svg
# merge 21 22
python svg_stack.py --direction=h --margin=100 21.svg 22.svg > 2.svg
# merge 31 32
python svg_stack.py --direction=h --margin=100 31.svg 32.svg > 3.svg
# merge all
python svg_stack.py --direction=v --margin=100 1.svg 2.svg 3.svg > final.svg

note that you can change merge direction using v and h

Solution 5:[5]

I used Victor gem https://github.com/DannyBen/victor

first_svg = File.open("first.svg").read
second_svg = File.open("second.svg").read

first_content = first_svg.split("\n")[1..-2].join(", ")
second_content = second_svg.split("\n")[1..-2].join(", ")

svg = Victor::SVG.new width: "100%", height: "100%"
svg << first_content
svg << second_content

svg.save 'final.svg'

Solution 6:[6]

maybe you can use svg-sprite, it's a nodejs tool

svg-sprite is a low-level Node.js module that takes a bunch of SVG files, optimizes them and bakes them into SVG sprites

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3
Solution 4 xihajun
Solution 5 kapil chouhan
Solution 6 oxygen