包含SVG图像的HTML框与图像的纵横比不匹配

时间:2013-11-25 22:46:57

标签: html css google-chrome svg

我正在尝试使用preserveAspectRatio="xMidYMid meet"缩放SVG图像以适合其容器,这是默认设置,但我仍然为了清晰起见而指定它。使用下面指定的CSS和SVG,缩放功能就像我想要的Chrome一样。但是,在IE和Firefox中,问题在于多边形是以保留的宽高比缩放,但背景不是。无论容器的纵横比如何,背景仍然填充整个容器。在JSFiddle或下面的代码中,容器的背景应该是绿色,图像的背景应该是灰色的,灰色部分是一个围绕蓝色多边形的所有四个角的正方形,因为蓝色多边形是相同的高度和宽度为正方形viewBox

换句话说,如果容器的高度>宽度,我想在灰色/蓝色SVG图像的上方和下方看到绿色,如果容器的宽度>高度,我想在灰色/蓝色SVG图像的每一侧看到绿色。

任何想法如何让我在所有支持SVG的浏览器中看起来都像我想要的那样?

http://jsfiddle.net/sJYEa/

<!DOCTYPE html>
<html lang="en">
<head>
<style>

html, body{
    height: 100%;
    margin: 0;
}

#container {
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
    width: 80%;
    height: 80%;
    margin: auto;
    border: 5px solid black;
    background-color: green;
}

#testSVG{
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
    max-width: 100%;
    max-height: 100%;
    margin: auto;
    background-color: gray;
}

</style>
<title>Scratch Pad</title>
</head>
<body>

<div id="container">
    <svg
       xmlns="http://www.w3.org/2000/svg"
       version="1.1"
       id="testSVG"
       viewBox="0 0 300 300"
       preserveAspectRatio="xMidYMid meet"
       width="5000"
       height="5000">
        <polygon points="150,0 300,150 150,300 0,150" style="fill:blue;" />
    </svg>
<!--
    <img id="testSVG" src="test.svg"/>
-->
</div>

</body>
</html>

我会试着预测一些人可能会遇到的问题:

问:为什么要使用CSS而不是仅仅更改SVG绘图?

A:我计划不仅设置背景,还设置border-radius的边框,可能是阴影,也许是背景纹理,并使用{{动态更改它们1}},:hover:focus伪类,这些我知道如何在CSS中做,但不知道如何在SVG中做。此外,我将不得不为旧浏览器设置PNG后备,如果我将背景,边框等设置为图像本身的一部分,这意味着我需要多个版本的PNG,具体取决于应用了哪些伪类。出于这些原因,我更喜欢使用CSS边框和背景,而不是添加额外的SVG元素。

问:为什么使用绝对定位来居中:active#testSVG不应该为你处理定位吗?

A:这也是我的想法,但事实并非如此。如果没有绝对定位和xMidYMid,Chrome会将图像绘制在容器的左上角,然后在调整容器大小时显示错误的缩放。

问:当您通过margin: auto标记引用SVG图像而不是将SVG内联时,您是否发现了不同的行为?

A:是的。当我通过<img>标记引用SVG时,除非我在{{<img>中使用widthheight属性,否则IE不会保留图像的宽高比1}}元素,但在这种情况下,如果容器的高度&gt; Chrome将仅显示绿色背景。宽度,如果容器的宽度不是>高度。在任何情况下,IE都不会显示绿色背景。

问:为什么要为100%元素的<svg>svg属性使用如此大的值?

答:对于指定的widthheight,浏览器似乎很乐​​意将DOWN缩放图像以填充容器,但拒绝将图像缩放到填满容器。 (这不是width属性中height的含义吗?!)没有指定的meetpreserveAspectRatio(即使用默认值width ),Chrome在肖像与风景中表现出不同的行为,如上一个答案中所述。至少按照我目前的方式,它在一个浏览器中的工作方式与我想要的完全相同....

问:我想我可以让它像您想要的那样工作,但我需要将图像包装在一个额外的非语义元素中。那可以吗?

A:是的!我加入了HTML的简单而纯粹的语义驱动,但是迂腐的优先级应该始终低于实用性和功能性。

那么,再次,关于如何让它在其他浏览器中像我想要的那样工作的任何想法?

1 个答案:

答案 0 :(得分:1)

我找不到任何一致的方法只用CSS做到这一点。但是,我确实找到了一个适用于使用SVG的浏览器的解决方案。

我添加了<rect/>,填充了绘图后面的整个宽度和高度。然后我使用CSS设置<rect/>的{​​{1}}以使用您为SVG元素的fill分配的相同颜色。

My updated JSFiddle

谷歌浏览器 v31.0.1650.57(1650.57), Safari v7.0(9537.71)和 Firefox v23.0(2313.7.30) OS X 10.9 (13A603)