Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I have Multiple SVG images in a single file?

Tags:

Instead of doing the following:

<html>
<body>
  <embed src="circle.svg" type="image/svg+xml" /> 
  <embed src="square.svg" type="image/svg+xml" /> 
  <embed src="triangle.svg" type="image/svg+xml" />  
</body>
</html>

I would prever to do something like this

<html>
<body>
<embed src="shapes.svg" type="image/svg+xml" id="circle" /> 
<embed src="shapes.svg" type="image/svg+xml" id="square" /> 
<embed src="shapes.svg" type="image/svg+xml" id="triangle" />  
</body>
</html>

with a svg file that may look something like this

<?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 xmlns="http://www.w3.org/2000/svg" version="1.1" >

  <svg id="circle">
    <circle cx="100" cy="50" r="40" stroke="black"
    stroke-width="2" fill="red" />
  </svg> 

  <svg id="square">
    <rect width="100" height="100" style="fill:rgb(0,0,255);stroke-width:1;stroke:rgb(0,0,0)" />
  </svg>

  <svg id="triangle">
    <line x1="50" y1="0" x2="0" y2="50" style="stroke:rgb(255,0,0);stroke-width:2" />
    <line x1="50" y1="0" x2="100" y2="50" style="stroke:rgb(255,0,0);stroke-width:2" />
    <line x1="0" y1="50" x2="100" y2="50" style="stroke:rgb(255,0,0);stroke-width:2" />
  </svg>
</svg>

It seems as an SVG is just XML I should be able to store all my images in a single file that downloades a single time and is used throughout the site.

like image 376
Jeremy A. West Avatar asked Jan 31 '13 16:01

Jeremy A. West


People also ask

How do I combine multiple SVGs into one?

To merge multiple SVG files together, upload your vectors or drag n drop them to the editor. Next, place the files together either vertically, horizontally, or at any position. After you're done editing, download the merged SVG in multiple high-res formats.

Can an SVG contain another SVG?

The SVG format allows for the nesting of SVG graphics. It is possible for an “<svg>” elements, to be placed within another “<svg>” element. Though, within a nesting, the absolute placement is limited to the respective parent “<svg>” element.


3 Answers

Yes, but XML documents need a single root node. Yours has three. Try wrapping the three nodes in an svg element and move the namespace and version number to it. Seems to validate via http://validator.w3.org/check

<?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 xmlns="http://www.w3.org/2000/svg" version="1.1">     <svg id="circle">       <circle cx="100" cy="50" r="40" stroke="black"       stroke-width="2" fill="red" />     </svg>       <svg id="square">       <rect width="100" height="100" style="fill:rgb(0,0,255);stroke-width:1;stroke:rgb(0,0,0)" />     </svg>      <svg id="triangle">       <line x1="50" y1="0" x2="0" y2="50" style="stroke:rgb(255,0,0);stroke-width:2" />       <line x1="50" y1="0" x2="100" y2="50" style="stroke:rgb(255,0,0);stroke-width:2" />       <line x1="0" y1="50" x2="100" y2="50" style="stroke:rgb(255,0,0);stroke-width:2" />     </svg> </svg> 
like image 96
JayC Avatar answered Sep 20 '22 00:09

JayC


You can only have a single root node in an html document. Nevertheless there are various ways to achieve what you want.

One way is SVG Stacks which works by having all the drawings on top of each other and then just displaying the one you want to see using CSS.

Another way might be to have a shapes.svg like this with all the drawings in different places

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">

  <g transform="translate(0,0)">
    <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" />
  </g>

  <g transform="translate(0,200)">
    <rect width="100" height="100" style="fill:rgb(0,0,255);stroke-width:1;stroke:rgb(0,0,0)" />
  </g>
  <g transform="translate(0,400)">
    <line x1="50" y1="0" x2="0" y2="50" style="stroke:rgb(255,0,0);stroke-width:2" />
    <line x1="50" y1="0" x2="100" y2="50" style="stroke:rgb(255,0,0);stroke-width:2" />
    <line x1="0" y1="50" x2="100" y2="50" style="stroke:rgb(255,0,0);stroke-width:2" />
  </g>
</svg> 

And then use svgView to show just the bits you want.

<html>
<body>
<embed src="shapes.svg#svgView(viewBox(50,0,100,100))" style="width:100px;        height:100px" type="image/svg+xml" />
<embed src="shapes.svg#svgView(viewBox(0,200,100,100))" style="width:100px;height:100px" type="image/svg+xml"/> 
<embed src="shapes.svg#svgView(viewBox(0,400,100,100))" style="width:100px;height:100px" type="image/svg+xml"/>  
</body>
</html>

All of these do mean though that you use more memory in the UA as the whole svg file is loaded 3 times and you just see a part of it each time.

like image 44
Robert Longson Avatar answered Sep 21 '22 00:09

Robert Longson


Reference:

<svg alt="">
    <use xlink:href="shapes.svg#circle"></use>
</svg>
<svg alt="">
    <use xlink:href="shapes.svg#square"></use>
</svg>
<svg alt="">
    <use xlink:href="shapes.svg#triangle"></use>
</svg>

shapes.svg:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <symbol id="circle">
        <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" />
    </symbol>
    <symbol id="square">
        <rect width="100" height="100" style="fill:rgb(0,0,255);stroke-width:1;stroke:rgb(0,0,0)" />
    </symbol>
    <symbol id="triangle">
        <line x1="50" y1="0" x2="0" y2="50" style="stroke:rgb(255,0,0);stroke-width:2" />
        <line x1="50" y1="0" x2="100" y2="50" style="stroke:rgb(255,0,0);stroke-width:2" />
        <line x1="0" y1="50" x2="100" y2="50" style="stroke:rgb(255,0,0);stroke-width:2" />
    </symbol>
</svg>
like image 43
Stephen Sabatini Avatar answered Sep 19 '22 00:09

Stephen Sabatini