简体   繁体   English

具有viewBox和宽度的SVG在IE中未正确缩放高度

[英]SVG with viewBox and width is not scaling height correctly in IE

I'm trying to construct inline SVGs with viewBox attributes, but no explicit width or height attributes. 我正在尝试使用viewBox属性构造内联SVG,但没有明确的宽度或高度属性。 I'm setting the SVG's width to 100% using CSS. 我正在使用CSS将SVG的宽度设置为100%。 This should let the SVG scale to its wrapping container, maintaining the aspect ratio set up by the viewBox. 这应该让SVG缩放到它的包装容器,保持viewBox设置的宽高比。 In Chrome and Firefox, this works perfectly! 在Chrome和Firefox中,这非常有效!

Here's a minimal codepen example of what I'm talking about: http://codepen.io/pcorey/pen/amkGl 这是我正在谈论的最小代码示例: http ://codepen.io/pcorey/pen/amkGl

HTML: HTML:

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

CSS: CSS:

div {
  width: 400px;
}

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

text {
  font-size: 10px;
}

The viewBox is 100x10. viewBox是100x10。 The outer div is set to have a 400px width. 外部div设置为400px宽度。 That means that the SVG's height should be (and is in Chrome/Firefox) 40px. 这意味着SVG的高度应该是(并且在Chrome / Firefox中)40px。 BUT, in IE 11, the width is ALWAYS 150px (even when the div's width exceeds 1500px...) 但是,在IE 11中,宽度总是150px(即使div的宽度超过1500px ......)

Is there a nice way to fix this in IE? 有没有一种很好的方法来解决这个问题? Why can't IE handle the unknown height correctly? 为什么IE无法正确处理未知高度? I can use the " intrinsic aspect ratio " trick, but that is super ugly, requires another DOM element, and requires that I recompute the padding-top every time the wrapper resizes. 我可以使用“ 内在宽高比 ”技巧,但这是超级丑陋,需要另一个DOM元素,并要求我每次包装器调整大小时重新计算padding-top。

For more info on why I want to do this, I wrote a quick blog post about it: http://1pxsolidtomato.com/2014/10/08/quest-for-scalable-svg-text/ 有关我为什么要这样做的更多信息,我写了一篇关于它的快速博客文章: http//1pxsolidtomato.com/2014/10/08/quest-for-scalable-svg-text/

Thanks for the help! 谢谢您的帮助!

One workaround that should work in all browsers is to add a blank image to the container your SVG sits inside, which has the same dimensions as your SVG: 一个适用于所有浏览器的解决方法是将空白图像添加到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> 

In this case, your image should have natural dimensions of 1000px by 600px and be transparent (or matching the background of your .wrap container). 在这种情况下,您的图像应具有1000px到600px的自然尺寸并且是透明的(或与.wrap容器的背景相匹配)。 This will appropriate the size of the container the svg sits inside. 这将适合svg所在容器的大小。 The absolute position of the .viz element will allow it to sit on top of the image, utilizing it's height so nothing gets cut off. .viz元素的绝对位置将允许它坐在图像的顶部,利用它的高度,所以没有任何东西被切断。

Some browsers(IE and safari) will be use a default size to SVG if you don't put a certain height and width. 如果你没有放置一定的高度和宽度,一些浏览器(IE和safari)将使用SVG的默认大小。 That what is happening here. 这就是这里发生的事情。 You are right, the "intrinsic aspect ration" is requiring another Dom and css and will be nice if we can overcame this. 你是对的,“内在的方面比例”需要另一个Dom和css,如果我们能克服这个,那将会很好。

There is a solution to this, you can calculate and put the right height to padding-bottom and this will give the right "unknown height" you want. 有一个解决方案,你可以计算并将正确的高度放到padding-bottom,这将给你想要的正确的“未知高度”。 You can see a full solution here: http://codepen.io/tomkarachristos/pen/GZPbgZ 你可以在这里看到一个完整的解决方案: 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"
         width="100%" style="height: 1px;overflow: visible;
         /*without js:padding-bottom:55%*/"><text>hello</text>
  </svg>
    <svg viewBox="0 0 100 10" preserveAspectRatio="xMidYMin slice"
         width="100%" style="height: 1px;overflow: visible;"><text>Age</text>
  </svg>
</div>

and javascript: 和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(' '));
  });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM