It's not bad if I load an HTML page
img, svg {
background-color: #eee;
margin: 20px;
}
<div>
<img src="circle.svg"/>
<img src="square.svg"/>
</div>
with just a pair of SVG images
circle.svg
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 400 300" width="400" height="300">
<circle cx="200" cy="150" r="100"
stroke="red" fill="blue" stroke-width="10" />
</svg>
square.svg
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 400 300" width="400" height="300">
<rect x="100" y="50" width="200" height="200"
stroke="green" fill="gray" stroke-width="10" />
</svg>
but with over a hundred SVG images, the server gets excessively hit by requests.
One solution is to serve the static files from a dedicated server, but this only dodges the problem. The number of requests remains high.
How can I bundle many SVG images inside just one?
The following is a combination of gael's and maqam7's answers, with a bug fix and some details.
First, we combine the two SVGs into one. (We write our own script, use an editor's macros, use one of the web sites that do it, or do it by hand.)
sprite.svg
When we want a circle or a square, we
use
thexlink:href
attribute (deprecated but continue to use it), which will invoke a sub-sprite.There is no need to include the sprite in the
body
as the sprite is referenced within each
svg
element.Hence there is no need to hide the global sprite.
Only the sub-parts appear.
One caveat: Chrome loads an
img
andsvg
directly, but will refuse to loaduse
/xlink:href
unless you run a local server.Remaining issue(s)
I'm not sure this is optimal. It may be that two requests continue to be sent. It's just that the cache will catch the second as identical. No harm is done. Still, loading once via a hidden
svg
may be a better approach, if someone can fill in the details.You could use a SVG sprite generator to create one big file with all images aligned in it.
SVG sprite generator will also generate a CSS file in which each individual SVG will be represented with a specific class.
In you HTML you just have to call each image by its class name.
A basic sprite.css could be :
And then in your html file you could just call:
It sounds like you need an SVG sprite. I use this trick all the time. It's great. Just make your
svg
blockssymbol
elements and nest them inside ansvg
like this:Note that you don't want the
xlmns
attribute on the individualsymbol
elements, just the rootsvg
. And the rootsvg
doesn't need a viewBox attribute, since that is encoded in the childsymbol
elements.Then you call the symbols elsewhere in the HTML like this via the
<use>
tag:Lastly, you need to hide the sprite in CSS:
Here's a Fiddle to demonstrate. Good luck!