SVGs are not resizing correctly in Internet Explorer and there is unnecessary blank space around them

Recently, I made the decision to switch to using SVG symbols for one of my projects. However, I encountered a challenge as I needed these SVGs to be responsive. My main objective was to minimize the number of HTTP requests, leading me to explore the option of merging all SVG files into one SVG, defining symbols, and utilizing them as follows:

<svg style="display:none;">
<defs>
<symbol id="mys">
    <path fill-rule="evenodd" clip-rule="evenodd" fill="#3F77BC" d="
        // SVG path data here
    ">
</symbol>
</defs>
</svg>
<div style="position:relative;width:100%;background:blue;">
  <svg class="mys" viewBox="0 0 254 108" preserveAspectRatio="xMaxYMax meet" style="width:100%;">
    <use xlink:href="#mys"></use>
  <svg>
</div>

If you'd like to see this in action and observe the different behaviors across browsers, check out this jsfiddle link: http://jsfiddle.net/ws472q71/

Despite successfully getting this code to work in Firefox and Chrome, I faced compatibility issues with Internet Explorer. I tried various fixes suggested online but to no avail.

I'm seeking advice on what might be going wrong and if there are any alternative solutions that allow merging SVGs into a single file while maintaining responsiveness.

Your insights and suggestions would be greatly appreciated. Thank you!

Answer №1

After some exploration, it seems that Internet Explorer has a glitch where it fails to properly scale the SVG unless both width and height are provided.

To resolve this issue in IE, there is a clever workaround discovered by Nicolas Gallagher.

The solution involves using a <canvas> element. IE does have proper scaling for canvas elements. By adding a canvas within the <div> containing the SVG, you can ensure that the SVG displays at the correct size. Make sure the canvas has the same aspect ratio as your SVG.

<div style="position:relative;width:100%;background:blue;">
  <canvas width="254" height="108"></canvas>
  <svg class="mys" viewBox="0 0 254 108" preserveAspectRatio="xMaxYMax meet">
    <use xlink:href="#mys"></use>
  </svg>
</div>

Applying CSS:

canvas {
    display: block;
    width: 100%;
    visibility: hidden;
}

svg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
}

canvas {
    display: block;
    width: 100%;
    visibility: hidden;
}

svg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
}
<svg style="display:none;">
<defs>
<symbol id="mys">
    <path fill-rule="evenodd" clip-rule="evenodd" fill="#3F77BC" d="M222.1,77.7h-10.3c0.1-0.8,0.2-1.4,0.2-2.3
        c0-8.5-6.9-15.4-15.4-15.4c-8.5,0-15.4,6.9-15.4,15.4c0,0.9,0.1,1.5,0.2,2.3h-9.3v4h-24.9v-5.2H89.4c0-0.3,0-0.6,0-0.9
        C89.4,67.1,82.5,60,74,60s-15.4,6.9-15.4,15.4c0,0.3,0,0.6,0,0.9h-6.2V60.7h4.3l5.3-5.3h22.8L74.3,44.9l-13.5-3.6l0.5-1.7
        l-16.5-4.4c-0.3,0.1-0.7,0.2-1,0.2l0,21.4h2v7.2c0,0-2,0.6-1.9,1.3c0.1,0.7,4.1,2.6,3.4,5.5c-0.6,2.9-1.6,4.8-4.4,4.5
        c-2.7-0.3-3.4-1.4-3.4-2.6c-0.1-1.2,0-3,0-3L38,67.9c0,0,2-0.5,2.6,1.1c0.6,1.5-0.2,2.7,0.6,3.5c0.8,0.8,4.1,1.4,4.1-1.1
        c0-2.5-0.5-2.4-2.1-3.6c-1.7-1.2-3.4-2.8-3.4-3.3c0-0.5-0.1-7.7-0.1-7.7h2.1l0-21.7c-1.4-0.7-2.5-2.1-2.5-3.8
        c0-2.3,1.9-4.2,4.2-4.2c2,0,3.6,1.4,4.1,3.2l15.3,4.1l0.4-1.6l55.8,15.1h28.1c0,0,0-23.5,0-26.2c0-2.7,2.1-2.6,2.1-2.6
        s32.5-0.5,35.1,0.5c2.7,1,3.3,3.7,3.3,3.7h-2l5,11.6c0,0,7.3,4.6,17.6,7.6c10.3,3,13.6,7.6,13.6,7.6l-1,17.6l1.3,2V77.7z
         M81.5,46.8l8.6,8.6h9.3l2.9-2.9L81.5,46.8z M175.5,25l-17.4-0.1v12.6h9.6l2.7,2.7h6.6L175.5,25z M183,23.7h-4c0,0,2,6.6,3,9.9
        s0.9,4.2,2.7,4.2c1.9,0,4.2,0,4.2,0L183,23.7z M74.2,63.8c6.8,0,12.3,5.5,12.3,12.3S81,88.4,74.2,88.4c-6.8,0-12.3-5.5-12.3-12.3
        S67.4,63.8,74.2,63.8z M196.6,63.8c6.8,0,12.3,5.5,12.3,12.3s-5.5,12.3-12.3,12.3s-12.3-5.5-12.3-12.3S189.8,63.8,196.6,63.8z"/>
</symbol>
</defs>
</svg>
<div style="position:relative;width:100%;background:blue;">
  <canvas width="254" height="108"></canvas>
  <svg class="mys" viewBox="0 0 254 108" preserveAspectRatio="xMaxYMax meet">
    <use xlink:href="#mys"></use>
  </svg>
</div>

This technique works whether you need to match the width or height of the SVG.

Answer №2

For those struggling to apply this solution or experiencing difficulties with external SVG files rather than inline SVG code:

It is crucial to ensure that your SVG file, when edited in a text editor, includes the viewBox and preserveAspectRatio attributes within the opening <svg> tag. Without these attributes, no matter what adjustments you make, the SVG will not scale properly in Internet Explorer, even though it may scale correctly in other browsers.

Once these attributes are included, you can set the width/height of the image element importing the SVG to 100% and use max-width or max-height to control scaling, resulting in the expected behavior. However, alignment issues may still arise.

Answer №3

While Nicolas Gallagher's solution was effective, I encountered some responsiveness issues when adjusting the viewport size. Here is the fix I implemented:

 <div class="container">
    <canvas width="3" height="1"></canvas>
    <svg class="mys" viewBox="0 0 254 108">
         <use xlink:href="#mys"></use>
    </svg>
 </div> 

I added "max-width:100%;" to the "container" class:

.container{
     position: relative;
     display: inline-block;
     height: 550px;
     max-width: 100%;
}

This fix may not address all scaling issues. You may still need to use media queries to adjust the height accordingly, but at least the svg element will now stay within its container. Hopefully this solution proves helpful for someone.

Answer №4

If you're dealing with <img> elements, you can rephrase it in the following manner.

Code Snippet for HTML:

<div class="ie-svgHeight">
  <img src="path.svg" class="ie-svgHeight-img">
  <canvas class="ie-svgHeight-canvas"></canvas>
</div>

Code Snippet for SCSS:

.ie-svgHeight {
  position: relative;

  &-canvas {
    display: block;
    visibility: hidden;
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
  }
  &-img { height: 100%; }
}

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

Exploring the Power of JQuery with Hover Effects and SlideToggle

I was struggling to keep the navbar displaying without it continuously toggling when my pointer hovered over it. I just wanted it to stay visible until I moved my pointer away. <script> $(document).ready(function(){ $(".menu-trigger").hover(funct ...

Increasing the div's size to exceed the dimensions of the screen

My issue pertains to the background image on my website. I have set a background image for the body and centered it horizontally. Each page includes a paragraph below the header, each with a different size, causing scrolling. The problem is that the backgr ...

Is there a way to make my modal appear only when the "New" option is clicked?

Is there a way to make my modal in VueJS open only when I click on the "New" option? <select v-model="input.des" @change="$refs.modalName.openModal()"> <option value="A">A</opt ...

Enhance user interactivity on your website by incorporating jQuery and CSS for

<table id="tab"> <tr aaa="one" bbb="ooo"><td>xxx</td><</tr> <tr aaa="two" bbb="one"><td>xxx</td><</tr> <tr aaa="three" bbb="one"><td>xxx</td><</tr> ...

Improper headings can prevent Chrome from continuously playing HTML5 audio

Recently, I encountered a peculiar and unlikely issue. I created a custom python server using SimpleHTTPServer, where I had to set my own headers. This server was used to serve .wav files, but I faced an unusual problem. While the files would play in an ...

What could be causing the reliability issue with this particular Angular JS code for dropdown menus?

Attempting to create a dynamic country-city dropdown menu using AngularJS <div> Country: </br> <select data-ng-model="country" ng-options="country.name for country in countries" data-ng-change="updateCountry(country) ...

Is there a way to customize the font size of Material UI Autocomplete?

I'm currently trying to customize the Material UI Autocomplete component with my own CSS. Specifically, I aim to adjust the font size of the input field. Below is my current implementation: <Autocomplete style={{ width: 200, height: 60, ...

Learn the process of downloading a pdf file with vuejs and bootstrap-vue

Having trouble uploading a PDF file to my browser and then downloading it afterwards. The upload is fine, but the download isn't working. This is how I am uploading: <b-form-file v-model="form.file" :state="Boolean(form.file)" placeholder="Choose ...

Updating values in MySQL using PHP requires two consecutive reloads

Hey there! I recently created a message deletion button, but for some reason, it takes two reloads to see the changes pop up. The rest of my code is working fine, so I won't be sharing that part here... <?php while($r = $replies->fet ...

What are the ways to personalize the material UI select component?

I am looking to customize a MUI select component that I have rendered on a dark background. My goal is to make the outline and all its contents light colors, specifically grey and white. So far, I have successfully changed the outline and text contents to ...

Managing content in two separate divs at the same time using AJAX

I am curious to know how I can achieve a functionality where editing the text field on the left will automatically update the text field on the right. I have a feeling that it involves using AJAX, and I would like to implement it as well. Can anyone guid ...

In search of a regular expression for identifying any of several classes

In the process of upgrading all my websites, I decided to redesign them so that all URL's default to lower case. This meant changing all image names and paths to lower case as well, which was accomplished using regexes. However, this action inadverten ...

What is the best way to add a gradient background image to a container that also has margins?

I am currently working on a push menu that shifts the main content container by adding margin-left to it. I am aiming to achieve a background image effect similar to what is seen on . Here is the progress I have made so far in my codepen: https://codepen ...

Encircling a particular group of cells with a border

I have completed the component with a table layout. My current challenge is figuring out how to surround a range of selected cells with a border, similar to the first cell in the group shown below: https://i.stack.imgur.com/5Euht.png I attempted using d ...

What is the procedure for adding a JavaScript function to an HTML element that was exclusively created in JavaScript?

I am trying to dynamically change the background color of a row in a table when selecting an object from a dropdown list, but only if the selected number is even. The challenge I am facing is that the objects are created using JavaScript and not directly i ...

Tips for aligning a menu that expands from the side to the center

I'm trying to center the menu on my webpage, but the issue is that it's stretching from the sides. Here's a sample image of the menu layout: I'm struggling to figure out how to fill the empty space on the left side of the menu. ...

Creating custom styles using Material-UI's makeStyles function with both before and after

Currently, I'm tasked with a project that involves utilizing the CSS code below. .hexagon, .hexagon::before, .hexagon::after { width: 67px; height: 116px; border-radius: 18%/5%; } I am wondering if there is a method to apply the specified style ...

What is the syntax for implementing conditional statements within the style jsx of Next.js?

Recently, I've been exploring the use of <style jsx> in my Next.js project and encountered a scenario where I needed to style an element based on a conditional statement. Additionally, my project relies on tailwindCSS for styling: <div classN ...

Enhancing the functionality of hidden input fields using jQuery

I'm looking to dynamically update the value of a hidden input element when a button is clicked. Here's what I have so far: Hidden Input Element: <input type="hidden" value="action" id="action" /> Buttons: <INPUT name=submit value=~#S ...

Retrieve the HTML content from the string that is returned

I have the string containing a list structure in my code-behind file: string xmlContents = "<ul><li>Installation<br /><ul><li>Startup</li><li>Getting there</li><li>Steps</li>" + ...