Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SVG stacking causes distortions

Tags:

html

css

svg

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:

US flag icon without distortion

As you can see, it looks fine.

But when I stack it in front of the UK flag, it looks like:

US flag icon with distortion

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?

like image 423
Siler Avatar asked Dec 28 '14 19:12

Siler


People also ask

Why are my svgs blurry?

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.

Can svgs be nested?

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.


1 Answers

No idea about stacking and target. But I know two simple methods.. may be those can help you out in an easier way.

  1. When you have chosen different svg icons from net or even from computer but each icon is separate.
    • There is a website 'icomoon.io', where we can choose different icons from online libraries or your custom svg icons from your computer.
    • Open 'https://icomoon.io/app/'
    • Choose 'import icons' to upload custom icons from your computer.
    • At bottom of the page it has 'Add Icons From Library…' to choose icons from online libraries.
    • From 'select' tool (At Top) select multiple icons as you like.
    • After selecting multiple icons choose 'Generate SVG,PNG,PDF' button at bottom.
    • Then to combine all of them in a single file, click on 'settings icon' located just next to the 'Download' option in first button at bottom left.
    • Choose 'Include Tiles (CSS Sprite) from it.
    • Put appropriate margins and number of icons in a row as you like and then download the combine sprite with its xml code in demo.html and css definitions in style.css.
  2. When you have already created single SVG file of multiple icons using 'AI' or any other software.
    • Just upload(import) that file to icomoon.io and click on 'Generate SVG,PNG,PDF' button and download the sprite xml file.
like image 76
Aabha Pandey Avatar answered Oct 16 '22 20:10

Aabha Pandey