width/height 的 SVG 无法在 IE9/10/11 上缩放

SVG with width/height doesn't scale on IE9/10/11

IE 9/10/11 存在一个已知问题,如果您有一个 SVG 文件,其中 <svg> 元素指定了宽度和高度,然后您使用 [=15= 缩放 SVG 图像] 和 height 属性的 <img> 标签,IE 无法正确缩放图像。

我已经 运行 解决了这个问题。我有一系列 SVG 标志图标。对于美国国旗图标,SVG对象写为:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="480" width="640">

<!-- elements to draw flag .. -->

</svg>

And here's the full source for the SVG.

我将 SVG 插入带有 <img> 标签的 HTML 文档中,然后 down-scale 将其插入到 20x15:

在 Chrome 39 上,SVG 正确呈现如下:

但是在IE10上,它呈现如下:

所以,这里似乎发生的事情是,即使 IE10 将 <img> 元素的大小调整为 20x15,它也不会缩小 SVG - 所以我们最终只能看到 top-left 角旗帜图标,显示为纯蓝色框。

好的...所以这似乎是 documented solutions 的一个已知问题。一种解决方案是简单地删除 SVG 文件中的所有 widthheight 属性。这似乎有点危险,因为我不想搞砸实际设计。如果您有很多 SVG 文件,这也有点麻烦 - 需要更多脚本来处理文件。

更好的解决方案是使用 CSS 专门针对 IE10 中的 SVG 元素,这显然可以使用供应商特定的媒体查询:

@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
  img[src*=".svg"] {
    width: 100%; 
  }
}

好的,但我不明白这个解决方案。当我尝试上述操作时,IE10 只是扩展 SVG 的大小以填充整个父容器,这不是我想要的。好的,也许我可以通过将 SVG 宽度设置为 100% 来强制 IE 缩放 SVG,但随后限制父容器的大小。所以我将 <img> 包裹在宽度和高度为 20x15 的 DIV 中。但是......这只会导致与以前相同的问题:容器 DIV 固定为 20x15,但 SVG 不会缩小 - 所以我们最终得到的是 top-left 的蓝色角旗帜如前:

...所以,我可能只是不了解这个解决方案。我怎样才能 IE10/11 将旗帜图标缩小到 20x15?

从 SVG 标记行中取出高度和宽度。

当指定 viewBox、width 和 height 属性时,IE9、IE10 和 IE11 无法正确缩放添加了 img 标签的 SVG 文件。

可以通过删除widthheight 属性 并仅通过 CSS 操作它们来解决此问题。

img[src*=".svg"] {
  width: 100%; 
}

注意:如果您在 IE11 中放置 SVG 内联,则 SVG 标签中需要 width 和 height 属性,同时将 SVG 标签的宽度设置为100% 使用 CSS,以便正确缩放。

当您的图像缺少 svg 元素上的 viewBox 属性时,就会发生这种情况。

您的应设置为:0 0 640 480。零是 X 和 Y 偏移量,640 和 480 对应于宽度和高度。它定义了一个代表图像边界的矩形。

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="480" width="640" viewBox="0 0 640 480">

这是我必须编写的节点脚本来解决同样的问题(对于包含多个 SVG 的文件夹),也许对某人有帮助:

'use strict'

const fs = require('fs')

fs.readdir(`./`, (err, flist) => {
    if (typeof flist != 'undefined') {
        flist.forEach((file, i) => {
            proceed(file)
        })
    }
})

function proceed(file){
    fs.readFile(`./${file}`, 'utf8', (err,svg) => {
        let out = svg.replace('<svg', '<svg viewBox="0 0 640 480" ')
        if (!svg.includes('viewBox')){
            fs.writeFile(file, out, err => {
                if(err) {
                    console.log(err);
                } else {
                    console.log("Saved: " + file);
                }
            }) 
        }
    })
}

查看来自 wonderflags 的@this flag 为您的答案,您需要设置 viewbox="0 0 640 480" 否则它将不起作用。 (欧盟旗帜)

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" height="480" width="640" viewBox="0 0 640 480"><defs><g id="d"><g id="b"><path d="M0-1l-.3 1h.5z" id="a"/><use transform="scale(-1 1)" xlink:href="#a"/></g><g id="c"><use transform="rotate(72)" xlink:href="#b"/><use transform="rotate(144)" xlink:href="#b"/></g><use transform="scale(-1 1)" xlink:href="#c"/></g></defs><path fill="#039" d="M0 0h640v480H0z"/><g transform="translate(320 242.263) scale(23.7037)" fill="#fc0"><use height="100%" width="100%" xlink:href="#d" y="-6"/><use height="100%" width="100%" xlink:href="#d" y="6"/><g id="e"><use height="100%" width="100%" xlink:href="#d" x="-6"/><use height="100%" width="100%" xlink:href="#d" transform="rotate(-144 -2.344 -2.11)"/><use height="100%" width="100%" xlink:href="#d" transform="rotate(144 -2.11 -2.344)"/><use height="100%" width="100%" xlink:href="#d" transform="rotate(72 -4.663 -2.076)"/><use xlink:href="#d" transform="rotate(72 -5.076 .534)"/></g><use height="100%" width="100%" xlink:href="#e" transform="scale(-1 1)"/></g></svg>

在使用带有 boostrap img-fluid 的内联 SVG 时遇到了很多麻烦。 SVG 总是以错误的高度呈现。我使用下面的代码来修复它。在 IE10 和 IE11 中测试。

    @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
        svg.img-fluid {
            position: absolute;
        }
    }