I'm trying out the SVG stacking technique to enable multiple icons stacked in a single file, requiring only a single HTTP request from the browser. The technique is described pretty thoroughly here.
Basically the idea is that you put multiple SVG elements into a single SVG file, and use CSS styling to hide all icons, except for the icon you currently want to display. You select the icon you currently want to display using the CSS :target
selector.
The technique works for me, except stacking multiple icons causes weird distortions in the displayed icon, even though all other icons are hidden.
In the example I'm working with, I simplified this to stacking only two icons: an US flag icon and an UK flag icon.
The (simplified) SVG file is:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg153" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="480" width="640" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
<svg:style
xmlns:svg="http://www.w3.org/2000/svg" type="text/css">
.i { display: none; }
.i:target { display: block; }
</svg:style>
<svg:svg id="uk" xmlns:svg="http://www.w3.org/2000/svg" class = "i" height="480" width="640" version="1.1">
<!-- SVG elements to draw UK flag -->
</svg:svg>
<svg:svg id="us" xmlns:svg="http://www.w3.org/2000/svg" class = "i" height="480" width="640" version="1.1">
<!-- SVG elements to draw US flag -->
</svg:svg>
</svg>
Note that the CSS is embedded within the SVG file, in a <svg::style>
element. The CSS is simply:
.i { display: none; }
.i:target { display: block; }
This way, any svg::svg
element with class="i"
is automatically invisible, unless we specifically target it in the SVG url. So this way, to display a US flag icon, I would use the following HTML snippet:
<img
src="flags.svg#us"
width="80"
height="60"
alt="SVG Stacked Image"
/>
And of course, to display the UK flag I would change it to src="flags.svg#uk"
Anyway, all of this works wonderfully... except for a strange image distortion which occurs in both Firefox and Chrome when I stack the images.
Here's a screenshot of the US flag when I remove the (hidden) UK flag from the SVG file:
As you can see, it looks fine.
But when I stack it in front of the UK flag, it looks like:
As you can see, the image becomes strangely distorted - it almost looks like what happens to a low-quality JPEG when you get a lot of "artifacts" in the compressed image.
So why exactly is this happening? The other images stacked with the US flag icon are all invisible, so why should they effect the visible icon at all?
I Googled around a lot looking for answers, and although there are definitely many issues and "gotchas" with the SVG stacking technique, they all relate to cross-browser compatibility. However, the technique works fine on most newer browsers up to and including IE9. Also, the distortion happens in both Firefox and Chrome, so this isn't likely to be some cross-browser issue, but rather something I'm doing wrong.
So, what is causing this weird distortion when I apply the SVG stacking technique?
The problem with that is your browser may struggle to display the SVG logo properly, without scaling, since it will try to be as large as possible, struggling to fit in an area as small as your logo. That's why I would always recommend specifying the width and height in terms of pixels.
However, there is a way to place SVG forms relatively within an SVG graphic. The SVG format allows for the nesting of SVG graphics. It is possible for an “<svg>” elements, to be placed within another “<svg>” element.
No idea about stacking and target. But I know two simple methods.. may be those can help you out in an easier way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With