将方形svg放置在屏幕中央,按比例缩放以适应屏幕的宽度和高度

时间:2017-02-24 20:10:45

标签: html css svg

这似乎是一个愚蠢的问题,可能是一个骗局,但我暂时找不到一个好的解决方案,所以最后不敢问。

我想在html文档中放置一个<svg>元素并满足以下要求:

  1. 图像被放置为<svg> html5元素,而不是外部svg文件。 (实际上,我想用D3.js动态生成它。)
  2. 图像垂直和水平放置在屏幕中央。
  3. 图像的实际尺寸不应超过某个预定义值(如15cm × 15cm)。
  4. 如果当前屏幕的宽度或高度小于15cm,则应以适合屏幕的方式缩放图像(保留纵横比)。不应剪裁图像的任何部分。图像应放在中心。
  5. 它与this article中描述的要求基本相同。它说我应该使用preserveAspectRatio="xMidYMid",但没有举例说明如何做到这一点以及它如何与文章中描述的其他技巧相对应。 This article建议preserveAspectRatio="xMidYMid meet",但我再也无法复制那里提供的示例以满足我的所有要求。

    我目前的代码是这样的,但它不适合身高,也不会垂直居中。

    &#13;
    &#13;
    .svg-container {
      height:100%;
      width:100%;
      max-height:15cm;
      max-width:15cm;
      margin: 0 auto;
    }
    &#13;
    <div class="svg-container">  
    <svg id="picture" preserveAspectRatio="xMidYMid meet" viewBox="0 0 100 100">
      <circle cx=50 cy=50 r=50></circle>
    </svg>
    </div>
    &#13;
    &#13;
    &#13;

6 个答案:

答案 0 :(得分:4)

如果SVG的宽高比是给定的,则以下工作。如果SVG的宽高比是动态的,你必须使用JavaScript,我相信。

此代码段适用于现代浏览器,并充分利用相对较新的vmin viewport-percentage length。浏览器支持为pretty good。对于水平和垂直居中,可以使用flexbox布局模式。同样,浏览器支持为pretty good

诀窍是SVG的尺寸是相对于屏幕的宽度或高度设置的,以最小者为准。这意味着即使我们将其设置为100vmin,SVG也能保证适合屏幕(但几乎没有)。为了强制执行最大尺寸,使用了良好的旧max-widthmax-height,与使用它们完全相同。

&#13;
&#13;
html, body {
  /* ensure that all of the viewport is used */
  width: 100%;
  height: 100%;
  /* ensure that no scrollbars appear */
  margin: 0;
  padding: 0;
  
  /* center SVG horizontally and vertically */
  display: flex;
  align-items: center;
  justify-content: center;
}

#picture {
  /* ensure 1:1 aspect ratio, tweak 50 to make SVG larger */
  width: 50vmin;
  height: 50vmin;  
  /* set some maximum size (width and height need to match
   * aspect ratio, 1:1 in this case */
  max-width: 200px;
  max-height: 200px;
}
&#13;
<svg id="picture" viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="50"></circle>
</svg>
&#13;
&#13;
&#13;

答案 1 :(得分:4)

试试这个css:

{{1}}

结果如下: https://jsfiddle.net/twe9jfkf/

这是你试图实现的目标吗?

答案 2 :(得分:2)

而不是css,你可能想尝试使用svg的宽度/高度,并通过getBBox()计算viewBox 一个基本的例子如下所示:

<!DOCTYPE HTML>

<html>

<body>
<svg>
  <circle cx=50 cy=50 r=50 fill=red />
</svg>

<script>
//--onload, onresize----
function sizeSVG()
{
	var mySVG=document.getElementsByTagName("svg")[0]

  	var svgW=window.innerWidth
	var svgH=window.innerHeight

    var bb=mySVG.getBBox()
	var bbx=bb.x
	var bby=bb.y
	var bbw=bb.width
	var bbh=bb.height

    mySVG.setAttribute("viewBox",bbx+" "+bby+" "+bbw+" "+bbh )
    mySVG.setAttribute("width",svgW)
    mySVG.setAttribute("height",svgH)
}

document.addEventListener("onload",sizeSVG(),false)
window.onresize=sizeSVG
</script>

</body>

</html>

答案 3 :(得分:1)

flexbox解决方案将是我的首选。 由于其他人已经回答了这个想法,我想出了这种不同的方法。

基本上它是absolute centering technique并且依靠绝对位置和自动边距来使元素居中。

body {
  height: 100vh;
  margin: 0;
}

svg#picture {
  max-height: 15cm;
  max-width: 15cm;
  height:100%;
  width:100%;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin:auto;
}
<svg id="picture" preserveAspectRatio="xMidYMid meet" viewBox="0 0 100 100">
  <circle cx=50 cy=50 r=50></circle>
</svg>

答案 4 :(得分:0)

您是否尝试将图片作为背景添加到svg-container?

.svg-container {
  height:100%;
  width:100%;
  max-height:15cm;
  max-width:15cm;
  margin: 0 auto;
  background-image:url('yourSVG.svg');
  background-repeat: no-repeat;
  background-size: contain;
}

答案 5 :(得分:0)

您还希望对齐垂直吗?看这个

&#13;
&#13;
.vertical-align {
	height:1000px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.svg-container {
  	max-height:15cm;
  	max-width:15cm;
	height: 100%;
	width: 100%;
}
&#13;
<div class="vertical-align">
	<div class="svg-container">  
	<svg id="picture" preserveAspectRatio="xMidYMid meet" viewBox="0 0 100 100">
	  <circle cx=50 cy=50 r=50></circle>
	</svg>
	</div>
</div>
&#13;
&#13;
&#13;