SVGs not scaling properly in IE - has extra space

2019-01-01 14:12发布

问题:

I decided to switch to svg symbols for one of my projects - but need them to be responsive. The main idea is not to have multiple http requests, so I was thinking of merging all SVGs into one SVG, define symbols and use them as follows:

<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;\">
  <svg class=\"mys\" viewBox=\"0 0 254 108\" preserveAspectRatio=\"xMaxYMax meet\" style=\"width:100%;\">
    <use xlink:href=\"#mys\"></use>
  <svg>
</div>

Here is a jsfiddle, check the different behaviour in IE (I checked 11 but read that 9 has multiple issues as well): http://jsfiddle.net/ws472q71/

For the life of me I can\'t get this to work properly. The above code works correctly in Firefox and Chrome, but fails in IE. I read about IE issues, but I couldn\'t find anything that works.

What am I doing wrong?

Is there any other similar solution that can merge SVGs into one file and use them as responsive images?

Thanks!

回答1:

As you have discovered, IE has a bug where it doesn\'t scale the SVG properly if you don\'t provide both the width and height.

To get it working in IE, you can use a trick discovered (?) by Nicolas Gallagher.

http://nicolasgallagher.com/canvas-fix-svg-scaling-in-internet-explorer/

The trick uses a <canvas> element. IE does properly scale canvas elements. So if you place one in the <div> with the SVG, the SVG will end up the correct size. You just need to give the canvas 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>

with 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>

The trick works whether you are trying to get it to match a width or a height.



回答2:

On a side note to help anyone struggling to implement this fix or finding its not working with external svg files rather than in-page svg markup

You need to ensure that when editing your svg file in a text editor it is not missing viewBox or preserveAspectRatio options in the opening tag. If these are missing regardless of what fixes you apply the svg will still not scale in IE - even though it\'ll scale in other browsers without issue.

If these options are set you can define the width/height on the image element used to pull in the svg to 100% and use max-width or max-height to limit the scaling and it will perform as expected. Though - you could still get some alignment issues.



回答3:

Nicolas Gallagher\'s solution works great, however, I ran into some responsive issues as I decreased the viewport. I thought I would pass along the fix I used:

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

I updated the \"parent-div\" with max-width:100%;

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

This will not solve all your scaling issues. You will still have to use media queries to change the height as you go, but at least the svg doesn\'t blow out its container. Hope this helps someone.



标签: html css svg