带有 viewBox 和宽度的 SVG 在 IE 中无法正确缩放高度

Posted

技术标签:

【中文标题】带有 viewBox 和宽度的 SVG 在 IE 中无法正确缩放高度【英文标题】:SVG with viewBox and width is not scaling height correctly in IE 【发布时间】:2014-12-03 22:44:41 【问题描述】:

我正在尝试使用 viewBox 属性构建内联 SVG,但没有明确的宽度或高度属性。我使用 CSS 将 SVG 的宽度设置为 100%。这应该让 SVG 缩放到它的包装容器,保持 viewBox 设置的纵横比。在 Chrome 和 Firefox 中,这可以完美运行!

这是我所说的一个最小的 codepen 示例: http://codepen.io/pcorey/pen/amkGl

html

<div>
  <svg viewBox="0 0 100 10">
    <text x="1" y="9">hello</text>
  </svg>
</div>

CSS:

div 
  width: 400px;


svg 
  width: 100%;
  max-height: 100%;
  outline: 1px solid tomato;


text 
  font-size: 10px;

viewBox 是 100x10。外部 div 设置为 400px 宽度。这意味着 SVG 的高度应该是(并且在 Chrome/Firefox 中)40px。但是,在 IE 11 中,宽度总是 150 像素(即使 div 的宽度超过 1500 像素...)

在 IE 中是否有解决此问题的好方法?为什么 IE 不能正确处理未知高度?我可以使用“intrinsic aspect ratio”技巧,但这非常丑陋,需要另一个 DOM 元素,并且每次包装器调整大小时都需要重新计算 padding-top。

关于我为什么要这样做的更多信息,我写了一篇关于它的快速博客文章:http://1pxsolidtomato.com/2014/10/08/quest-for-scalable-svg-text/

感谢您的帮助!

【问题讨论】:

参见 使用 标签嵌入内嵌 SVG 部分 tympanus.net/codrops/2014/08/19/making-svgs-responsive-with-css 啊,是的,这行得通。我试过这样做,但我正在使用计算像素填充。如果我使用百分比来代替它,它会完美地工作。谢谢! 当您提出问题时,此文章不存在。它深入涵盖了该主题:How to Scale SVG 【参考方案1】:

一种适用于所有浏览器的解决方法是将空白图像添加到 SVG 所在的容器中,该容器的尺寸与 SVG 相同:

.wrap 
  position: relative;

img 
  width: 100%;
  height: auto;

.viz 
  position: absolute;
  top: 0;
  left: 0;
<div class="wrap">
  <img src="img/blank.png" />
  <div class="viz">
    <svg preserveAspectRatio="xMinYMin slice" viewBox="0 0 1000 600"></svg>               
  </div>
</div>

在这种情况下,您的图片应具有 1000 像素 x 600 像素的自然尺寸并且是透明的(或与 .wrap 容器的背景相匹配)。这将调整 svg 所在容器的大小。 .viz 元素的绝对位置将允许它位于图像的顶部,利用它的高度,因此不会被截断。

【讨论】:

【参考方案2】:

如果您没有设置特定的高度和宽度,某些浏览器(IE 和 safari)将使用 SVG 的默认大小。这就是这里发生的事情。你是对的,“内在方面比率”需要另一个 Dom 和 css,如果我们能克服这个问题会很好。

有一个解决方案,您可以计算并将正确的高度放在 padding-bottom 中,这将给出您想要的正确“未知高度”。 您可以在此处查看完整的解决方案: http://codepen.io/tomkarachristos/pen/GZPbgZ

<!--
xMidYMin: Align the midpoint X value of the element's viewBox with the midpoint X value of the viewport.
slice : the entire viewport is covered by the viewBox and the viewBox is scaled down as much as possible,
height: if you dont set >= 1px some browsers will not render anything.
-->
<div>
    <svg viewBox="0 0 100 10" preserveAspectRatio="xMidYMin slice"
          style="height: 1px;overflow: visible;
         /*without js:padding-bottom:55%*/"><text>hello</text>
  </svg>
    <svg viewBox="0 0 100 10" preserveAspectRatio="xMidYMin slice"
          style="height: 1px;overflow: visible;"><text>Age</text>
  </svg>
</div>

javascript

/*
Here we do the hack.
With the math type: percent * height/width
we are adjust the total height of an element who is depend in width using the padding-bottom.
You can put an inline padding-bottom if you want in html.
*/

$(function() 
  $('svg').each(function() 
    var svg = $(this);
    var text = svg.find('text');
    var bbox = text.get(0).getBBox();
    //the hack
    var calcString = "calc(100% * " + bbox.height/bbox.width + ")";
    svg.css("padding-bottom",calcString);

    svg.get(0).setAttribute('viewBox',
                           [bbox.x,
                            bbox.y,
                            bbox.width,
                            bbox.height].join(' '));
  );
);

【讨论】:

以上是关于带有 viewBox 和宽度的 SVG 在 IE 中无法正确缩放高度的主要内容,如果未能解决你的问题,请参考以下文章

使用带有 svg 图像的最大宽度时,IE 不保持纵横比

使用 CSS 更改 SVG Viewbox 大小

Internet Explorer 中的 SVG 太小

条形高度占据 viewBox 响应式 SVG 的整个高度

div背景图片拉伸的问题(SVG中的viewBox含义)

如果从 svg 中省略,viewBox 属性的默认值是多少?