IE浏览器中SVG图像无法正确缩放 - 存在额外空间

20

我决定在我的一个项目中转换为svg符号 - 但需要它们是响应式的。主要思想是不要有多个http请求,所以我考虑将所有SVG合并为一个SVG,定义符号并按如下方式使用它们:

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

这里有一个jsfiddle链接,请查看在IE中的不同行为(我检查了11,但读到9也有多个问题): http://jsfiddle.net/ws472q71/

我千方百计也无法让它正常工作。上述代码在Firefox和Chrome中正确工作,但在IE中失败了。我阅读了IE问题,但找不到任何有效的解决方法。

我做错了什么?

是否有其他类似的解决方案,可以将SVG合并为一个文件,并将其用作响应式图像?

谢谢!


SVG Stacks 对你有用吗? - KyleMit
不,目前还为时过早。我可以没有ie8支持,但不能没有Android支持。谢谢你指出来。 - scooterlord
看看这个使用jQuery的JS解决方案:https://stackoverflow.com/a/72216071/19074969 - user19074969
4个回答

42

正如您所发现的,IE存在一个bug,如果您没有提供宽度和高度,它就无法正确缩放SVG。

为了让它在IE中正常工作,您可以使用Nicolas Gallagher发现的技巧。

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

这个技巧使用了一个<canvas>元素。IE可以正确缩放画布元素。因此,如果您将其放置在带有SVG的<div>中,SVG最终会呈现出正确的大小。您只需要让画布具有与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>

使用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>

这个技巧可以用于调整宽度或高度,无论你希望两者相等还是不等。


非常好的答案。与此同时,我自己意识到我可以给SVG绝对定位,但无法避免使用相对父元素的padding bottom。这样做效果更好! :) 谢谢! - scooterlord
你是否将画布元素的宽度和高度设置为与SVG相同?难道没有不显式设置高度和宽度的方法吗?我希望能够轻松更换具有不同纵横比的SVG,而无需不断重新计算宽度和高度。 - thatidiotguy
对我来说,通过在CSS中将宽度设置为“1em”,我可以使用“font-size”属性缩放SVG,这也适用于图标 :) - gitaarik
2
我使用了一个 ::before 元素替代 canvas 元素,并将底部填充设置为相应的宽高比,以达到同样的效果。这样可以避免引入 hacky 的 canvas 元素。::before{ content:""; display:block; width:100%; padding-bottom:42.51968%; visibility: hidden; } - Andyweb

4

顺便提一下,为了帮助那些在实现此修复方法时遇到困难或发现它不能与页面外的SVG文件一起使用的人

请确保在文本编辑器中编辑SVG文件时,开头的<svg>标签内不缺少viewBoxpreserveAspectRatio属性。如果缺少这些属性,无论你采取什么修复措施,在IE中SVG仍然无法缩放——尽管它会在其他浏览器中正常缩放。

如果这些选项设置正确,您可以将用于拉取SVG的图像元素的宽度/高度定义为100%,并使用max-width或max-height来限制缩放,它将按预期执行。但是,你可能仍然会遇到一些对齐问题。


2

Nicolas Gallagher的解决方案非常好,但是当我减小视口时遇到了一些响应式问题。我想分享我使用的修复方法:

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

我使用max-width:100%更新了“parent-div”。
.parent-div{
     position: relative;
     display: inline-block;
     height: 550px;
     max-width: 100%;
}

这并不能解决你所有的缩放问题。当你进行高度变化时,你仍然需要使用媒体查询,但至少svg不会超出其容器。希望这能对某些人有所帮助。

-1
如果你正在使用 <img>,那么可以这样重写。
HTML
<div class="ie-svgHeight">
  <img src="path.svg" class="ie-svgHeight-img">
  <canvas class="ie-svgHeight-canvas"></canvas>
</div>

SCSS

.ie-svgHeight {
  position: relative;

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接