Stacking SVG elements can lead to distortion effects

Currently experimenting with the innovative SVG stacking method to integrate multiple icons into a single file, reducing the browser's HTTP requests. The details of this technique can be found in depth here.

In essence, it involves placing numerous SVG elements within one SVG file and utilizing CSS styles to hide all icons except for the one currently selected for display. To choose the visible icon, the CSS :target selector is employed.

The approach is successful for me, except when stacking multiple icons, peculiar distortions occur in the displayed image despite hiding all other icons.

In my example, I decided to stack only two icons: a US flag and a UK flag.

The simplified SVG file looks like:

<?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, inside a <svg::style> element. The CSS simply consists of:

.i { display: none; }
.i:target { display: block; }

In this manner, any svg::svg element with class="i" is automatically hidden unless targeted specifically in the SVG URL. Thus, to display a US flag icon, the following HTML snippet would be used:

<img 
    src="flags.svg#us" 
    width="80" 
    height="60" 
    alt="SVG Stacked Image" 
/>

Similarly, for displaying the UK flag, the code would be changed to src="flags.svg#uk"

Everything works smoothly, but a strange image distortion occurs when stacking images in both Firefox and Chrome.

Here's an image of the undistorted US flag after removing the hidden UK flag from the SVG file:

As evident, it appears fine.

However, when overlaying it on top of the UK flag, the image seems distorted as shown below:

The resultant image is oddly skewed - resembling what happens to low-quality JPEGs with compression artifacts.

Why does this distortion occur? All other images stacked with the US flag are invisible, so why do they impact the visible icon?

Extensive searches on Google uncovered various issues and pitfalls associated with SVG stacking primarily related to cross-browser compatibility. Despite successfully working across most modern browsers up to and including IE9, the distortion persists in both Firefox and Chrome, indicating a probable mistake on my part rather than a cross-browser issue.

Therefore, what exactly causes this unusual distortion post the application of the SVG stacking technique?

Answer №1

Unfamiliar with stacking and targeting icons? No worries! Here are two straightforward methods that might make things easier for you.

  1. If you have individual SVG icons sourced from the internet or saved on your computer:
    • Visit 'icomoon.io', a website where you can select icons from online libraries or upload custom SVG icons from your computer.
    • Go to ''
    • Use the 'import icons' feature to upload your own icons.
    • Scroll to the bottom of the page and click on 'Add Icons From Library…' to choose icons from online libraries.
    • With the 'select' tool (located at the top), pick multiple icons of your choice.
    • Once you've selected all the desired icons, hit the 'Generate SVG,PNG,PDF' button at the bottom.
    • To merge all the icons into one file, click on the 'settings icon' next to the 'Download' option in the first button on the bottom left corner.
    • Select 'Include Tiles (CSS Sprite)' from the settings menu.
    • Adjust margins and specify the number of icons per row according to your preference, then download the combined sprite along with its XML code in demo.html and CSS definitions in style.css.
  2. If you already have a single SVG file containing multiple icons created using software like Adobe Illustrator:
    • Simply import the file to icomoon.io and click on the 'Generate SVG,PNG,PDF' button to download the sprite XML file.

Answer №2

After experimenting with my own basic svgs, I didn't encounter any strange distortions. It seems likely that the issue lies with the svgs specific to the UK and US.

http://pastebin.com/dxVtTQKF

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Incorporating fontawesome icons ABOVE custom menu items in WordPress

In the process of customizing a menu in WordPress, I am looking to add fontawesome icons above each list item. In the past, I achieved this using the following code: <ul> <li> <a href="#"> <i class="fa fa-home"></i&g ...

Verify if there is a value in at least one of the multiple input fields

I have 4 input fields and I need to check if at least one of them has a value. If none of them are filled out, I want the function to stop. Below is the current code snippet I'm using but it's not working as expected because it doesn't ente ...

Do designers often manually adjust elements using media queries when working with Bootstrap?

Is it common practice to directly invoke media queries in order to manually adjust the layout of elements when using Bootstrap? In other words, if I have a custom element that I need to display or position in a specific way, is it acceptable to call the m ...

"Finding the Perfect Alignment: How to Center Legends in Firefox

The issue at hand An issue has been identified where the code functions as intended in Chrome, Opera, and IE but fails to work in Firefox: fieldset>legend { display: table; float: none; margin: 0 auto; } <fieldset> <legend>Legend ...

When the 'Show More' button is clicked, one Div will smoothly slide over another Div

I've been struggling for hours to find a way to make one DIV slide over another DIV below it instead of pushing it down. The setup is quite straightforward. I have a script that reveals more text when the 'Show More' button is clicked. Desp ...

Ending the jQuery Modal box

Struggling to create a simple modal on my own, and I'm facing some difficulties (probably because I'm more of an expert in jQuery - but let's not dwell on that too much). This is the HTML markup I have: <div id="modal-boxes"> < ...

Background positioning in IE8 does not display as intended

I'm experiencing an issue with the image background not displaying in IE8. You can view the page here, and the arrows on the accordion are not visible. Here is the CSS: .closed h2.accordion_h3 { background: url(mysource_files/down.png) no-rep ...

What is the quickest way to redirect a URL in WordPress?

Is it possible to redirect a URL instantly in WordPress using this script code? JavaScript Code: jQuery(document).ready(function() { var x = window.location.href; if (x == 'http://example.com/') { window.location.hr ...

What is the best way to embed a webpage into another webpage using frames?

I need help embedding an iframe on my website, , to display the items I am selling on eBay. This is my first time attempting to create an iframe. ...

Steer clear of altering line spacing in CSS

Here is the HTML structure that I am working with: <div id="id1"> <h1>my name </h1><h3><a href="mailto:myemail_id"><a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ff92869a929e9693969bbf878685d19 ...

Retrieve information from individual XML nodes in a parsed string

When making an Ajax call to retrieve XML data from a different domain using a PHP proxy to bypass cross-origin restrictions, I am unable to extract the values from the XML nodes and display them in my HTML tags. Despite no errors showing up in the browser ...

Prevent the appearance of a scrollbar on a fixed-position popup element

Whenever I click on a button, a Sidebar opens up and fills the entire screen due to its position being set to fixed. Here's how it looks with TailwindCSS: return ( <div className="fixed z-40 flex left-0 top-0 h-screen w-screen"> ...

Immutable value of a fixed attribute and the format of the element's date

I have a couple of inquiries regarding the internet TV site I am currently working on. First, I want the main subscription element to have an attribute called (ServerIP) with a fixed value that cannot be changed. However, the code I tried did not work as e ...

What is the best way to ensure the menu background aligns perfectly with the header in HTML/CSS?

Issue: Menu background doesn't align with header. (visible in the image provided below) VIEW IMAGE Any suggestions on how to resolve this alignment problem? CSS CODE : .header { margin:0px auto; max-width: 960px; } #header { height:30 ...

Ways of accessing an array within an if statement

I have a dashboard with admin privileges for my application. In this dashboard, the admin can select a user from a dropdown list. Once a user is selected, I make an AJAX call to retrieve the user's data and store it in a variable named $result. Howeve ...

Leveraging the power of map in an Angular typescript file

I've been attempting to populate a Map in Angular by setting values dynamically. When certain buttons are clicked, the onClick function is invoked. typeArray: Map<number,string>; Rent(movieId: number){ this.typeArray.set(movieId,"Rental ...

Unveiling the Quirk of Foundation 5: Grid Encounters a Popping

Recently, I encountered an issue with Foundation 5. Whenever I attempt to apply the "position:fixed" property on a "div" element that is part of the Foundation Grid, it causes the div to break out of the grid and align itself with the left edge of the ro ...

Obtaining the source code from a different domain website with the help of jQuery

Is there a way to extract part of the source code from a YouTube page without using server-side programming? I've tried cross-domain AJAX techniques like Yahoo YQL and JsonP. While Yahoo YQL allows me to grab part of the source code, I'm facing ...

Form is protected from XSS attacks

Here's a basic form that I'm attempting to exploit with XSS using Chrome. <?php echo $_GET['comment']; ?> <script>alert('from HTML')</script> <form method="GET" action=""> Name: <input t ...

Erase jQuery from the text

I am struggling with splitting or removing text from a filename. For example, if I have filenames like: 200726100_50-0002.JPG 230514008_60-0001.JPG The desired result should be: 230514008_60.JPG 200726100_50.JPG Am I not using the split function cor ...