在容器中居中大svg

时间:2017-09-15 13:50:35

标签: javascript css svg css-position

我试图将一个大的svg放在容器div中,同时最大化svg的大小并保持宽高比。

由于某种原因,svg显示正确,但width和height属性不正确,就像svg扩展到整个父级一样。

我如何才能使svg具有合适的尺寸?

请,这应该只用CSS解决,没有javascript。

另外,请注意,如果我用大图像替换svg,这是有效的。

var info = document.getElementById('info');
var svg = document.getElementById('svg');
var box = svg.getBoundingClientRect();

info.textContent = 'the ratio is ' + (box.width / box.height) + ' instead of 2.5! The yellow square is not in the viewBox, so why does it show up?';
.container {
  position: absolute;
  top: 40px;
  left: 40px;
  right: 40px;
  bottom: 40px;
}

.svg {
  position: absolute;
  max-height: 100%;
  max-width: 100%;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: gray;
}
<div class="container">
<svg id="svg" class="svg" width="1000px" height="500px" viewBox="0 0 10 5">
   <rect width="10" height="5" fill="black" />
   <rect x="-2" y="2" width="1" height="1" fill="yellow" />
</svg>
</div>
<div id="info"/>

1 个答案:

答案 0 :(得分:1)

从某种意义上说,你的svg已经按照你想要的方式放入容器中。实际上,您定义的大部分CSS都可以保留。 SVG元素应使用width: 100%, height: 100%定义,因此<svg>元素本身与其容器具有相同的大小。然后,viewBox定义的区域将根据属性preserveAspectRatio="xMidYMid meet"呈现到此视口中。 (隐含使用,即默认值):保留纵横比,最大尺寸适合内部,位于中间。

黄色rect的问题只是因为内容被剪切在视口的边缘,而不是 viewBox 。因此,在SVG中定义的内容可能仍然可见。

(最初的想法是在clip元素上支持<svg>样式属性,但它的概念太复杂,以至于无法使用,现在已弃用。)

现在最好的解决方案是将<svg>元素与另一个<svg>包装起来。内部的一个获得宽度和高度的绝对值,外部的一个获得与viewBox和width: 100%, height: 100%相同的值。

正如您所看到的,内部svg在其边缘处剪切内容,而外部svg将内容拟合到容器中。

请注意,您无法在内部svg上定义CSS background-color。这仅针对HTML定义,仅适用于外部HTML,因为它是HTML元素的直接子元素。如果您想要彩色背景,请使用适当的fill定义覆盖viewBox区域的矩形。

&#13;
&#13;
.container {
  position: absolute;
  top: 40px;
  left: 40px;
  right: 40px;
  bottom: 40px;
}

#svg1 {
  height: 100%;
  width: 100%;
  background-color: gray; /* clipped at the borders of the container! */
}
&#13;
<div class="container">
  <svg id="svg1" class="svg" viewBox="0 0 10 5">
    <svg id="svg2" width="10" height="5">
      <rect width="10" height="5" fill="black" /> <!--this is your background-->
      <rect x="-2" y="2" width="1" height="1" fill="yellow" />
      <ellipse cx="5" cy="2.5" rx="6" ry="3"
               fill="none" stroke="blue" stroke-width="0.2" />
    </svg>
  </svg>
</div>
<div id="info"/>
&#13;
&#13;
&#13;