首页 文章

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

提问于
浏览
23

我正在尝试使用viewBox属性构造内联SVG,但没有明确的宽度或高度属性 . 我正在使用CSS将SVG的宽度设置为100% . 这应该让SVG缩放到它的包装容器,保持viewBox设置的宽高比 . 在Chrome和Firefox中,这非常有效!

这里's a minimal codepen example of what I'我在谈论: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中,宽度总是150px(即使div的宽度超过1500px ......)

有没有一种很好的方法来解决这个问题?为什么IE无法正确处理未知高度?我可以使用“intrinsic aspect ratio”技巧,但这非常难看,需要另一个DOM元素,并且每次包装器调整大小时都要求我重新计算padding-top .

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

谢谢您的帮助!

2 回答

  • 4

    一个适用于所有浏览器的解决方法是将空白图像添加到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>
    

    在这种情况下,您的图像应具有1000px到600px的自然尺寸并且是透明的(或与.wrap容器的背景相匹配) . 这将适合svg所在容器的大小 . .viz元素的绝对位置将允许它坐在图像的顶部,利用它的高度,所以没有任何东西被切断 .

  • 3

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

    有一个解决方案,你可以计算并将正确的高度放到padding-bottom,这将给你想要的权利"unknown height" . 你可以在这里看到一个完整的解决方案: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>
    

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

相关问题