web-dev-qa-db-ja.com

viewBoxとwidthを使用したSVGは、IE

ViewBox属性を使用してインラインSVGを構築しようとしていますが、明示的な幅または高さ属性はありません。 CSSを使用してSVGの幅を100%に設定しています。これにより、SVGがラッピングコンテナーに合わせてスケーリングされ、viewBoxで設定されたアスペクト比が維持されます。 ChromeおよびFirefoxでは、これは完全に機能します!

ここに私が話していることの最小限のコードペンの例があります: 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は、幅が400ピクセルに設定されています。つまり、SVGの高さは40ピクセル(Chrome/Firefox内)でなければなりません。ただし、IE 11、幅は常に150pxです(divの幅が1500pxを超えている場合でも...)

IEでこれを修正する良い方法はありますか?なぜIE未知の高さを正しく処理できないのですか? " intrinsic aspect ratio "トリックを使用できますが、それは非常にく、別のDOM要素が必要であり、ラッパーのサイズが変更されるたびにパディングトップを再計算する必要があります。

これを行う理由の詳細については、それについての簡単なブログ記事を書きました: http://1pxsolidtomato.com/2014/10/08/quest-for-scalable-svg -text /

助けてくれてありがとう!

24
pcorey

すべてのブラウザーで機能する回避策の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>

この場合、画像は1000x600ピクセルの自然な大きさで、透明である(または.wrapコンテナの背景に一致する)必要があります。これにより、svgが内部にあるコンテナのサイズが適切になります。 .viz要素の絶対位置は、その高さを利用して何も途切れないように、画像の上に配置できるようにします。

4
Taylor Plante

特定の高さと幅を設定しないと、一部のブラウザー(IEおよびsafari)はSVGのデフォルトサイズを使用します。ここで起こっていること。あなたは正しい、「固有のアスペクト比」は別のDomとcssを必要としているので、これを克服できればいいでしょう。

これには解決策があります。正しい高さを計算してp​​adding-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"
         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(' '));
  });
});
3