Подтвердить что ты не робот

SVG с viewBox и ширина не правильно масштабируют высоту в IE

Я пытаюсь построить встроенные SVG с атрибутами viewBox, но не имеет явных атрибутов ширины или высоты. Я устанавливаю ширину SVG до 100% с помощью CSS. Это должно позволить шкале 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 должна быть (и находится в Chrome/Firefox) 40 пикселей. НО, в IE 11 ширина равна ALWAYS 150px (даже если ширина div превышает 1500px...)

Есть ли хороший способ исправить это в IE? Почему IE не может корректно обрабатывать неизвестную высоту? Я могу использовать трюк "внутреннее соотношение сторон", но это супер уродливо, требуется другой элемент DOM и требует, чтобы я перепродавал верхнюю часть каждого раза, когда обертка изменяет размер.

Для получения дополнительной информации о том, почему я хочу это сделать, я написал короткое сообщение в блоге об этом: http://1pxsolidtomato.com/2014/10/08/quest-for-scalable-svg-text/

Спасибо за помощь!

4b9b3361

Ответ 1

Некоторые браузеры (IE и сафари) будут использовать размер по умолчанию для SVG, если вы не установите определенную высоту и ширину. Это то, что здесь происходит. Вы правы, "внутреннему аспекту рациона" требуется еще один Dom и css, и будет приятно, если мы сможем преодолеть это.

Есть решение для этого, вы можете вычислить и поместить правильную высоту в padding-bottom, и это даст правильную "неизвестную высоту", которую вы хотите. Вы можете увидеть полное решение здесь: http://codepen.io/tomkarachristos/pen/GZPbgZ

<!--
xMidYMin: Align the midpoint X value of the element 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(' '));
  });
});

Ответ 2

Одним из способов обхода, который должен работать во всех браузерах, является добавление пустого изображения в контейнер, в котором находится 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>