Webkit浏览器中SVG高度计算不正确

32

我在使用 Raphael JS 渲染 SVG 数据,并使用响应式布局来随着浏览器窗口缩放 SVG。这些 SVG 的宽度/高度都设置为 100% ,并通过 JQuery 进行设置。包含这些 SVG 的元素的宽度设置为百分比,以保持布局的比例随着页面的调整而改变。

问题在于 Webkit 浏览器无法正确计算高度,在 SVG 图像周围添加了额外的像素(有时是数百个),这会破坏布局。

如果您在 Webkit 浏览器中打开以下链接,您将看到绿色的额外像素区域。如果您在 Safari 中使用开发人员检查器,则会看到报告的 SVG 大小大于显示的 SVG。

http://e-st.glam.ac.uk/simulationgames/svgheightbug/index.html

如果您在 Firefox 或 Opera 中打开此链接,则会看到正常工作的布局(这里的绿色是由我故意设置的边距引起的)。

IE8 也存在类似的问题,但使用 height:auto 可以解决,但在 Webkit 中不起作用。

是否有其他人遇到过这个问题?有没有什么解决方法?

我认为这可能是 Webkit 的一个 bug(已检查了 Nightly Build 版本,问题仍然存在),但在记录之前,我想先检查一下是否有其他人有解决方案。


我仍在努力理解您想要的是什么。我已将您的示例简化为一个(希望)更简单的测试用例:http://phrogz.net/SVG/find-a-room.xhtml 如果此文件显示了您的问题,请描述您想要看到的内容以及您实际看到的内容(以及使用的操作系统/浏览器/版本)。 - Phrogz
2
好的,我遇到的问题在所有版本的Webkit中都出现了(这包括Safari OS X和Windows,iOS上的Safari Mobile,以及Chrome OS X和Windows)。问题在于,尽管SVG显示的大小正确(其高度根据宽度比例确定,并且由于其容器设置为百分比,因此可以很好地无限缩放),但其高度报告不正确,这会导致容器比显示的SVG更高。 - Barry
从逻辑上讲,HTML通过容器内的内容来定义容器的高度;除非设计师明确限制。因此,在上面的示例中,SVG容器(在<section id="campus">中)的高度应与显示的SVG的高度相同。 - Barry
使用Safari开发工具检查SVG时,我的浏览器屏幕的当前宽度和SVG的尺寸为516x1075像素。你可以用肉眼看出SVG的高度不会超过它的宽度。在宽度为516像素时,SVG的高度为526像素(原始高度288像素/原始宽度282像素*当前宽度516=526像素),这是SVG显示的大小。但由于该高度值被错误地计算,<section id="campus">认为其高度应为1075,因此出现了绿色区域。 - Barry
以下的Javascript/JQuery代码解决了这个问题。function fixWebkitHeightBug(){ /* 调整校园元素大小 */ var campusW = 282; var campusH = 288; var curCampusW = $('#campus').width(); var newCampusH = heightInRatio(campusH,campusW,curCampusW); $('#campus').height(newCampusH); function heightInRatio(oH,oW,nW){ return (oH / oW * nW); } } $(window).resize(function() { fixWebkitHeightBug(); }); $(document).ready(function() { fixWebkitHeightBug(); }); - Barry
你有 viewBox 吗?你声明了适当的 preserveAspectRatio 值吗? - Joey
9个回答

73

1
我要补充的是,这个 bug 错误地计算了 SVG 的宽度和高度。也就是说,如果没有定义高度或最大高度,则自动高度将被错误计算;如果没有定义宽度或最大宽度,则自动宽度将被错误计算。在我的情况下,并且在使用绝对定位时,将 max-height/width 设置为百分比可能行不通,此时您可以使用一个非常大的 px 或 em 尺寸。在我的例子中,我使用了1000em,比任何 SVG 的大小都要大得多。 - curiouser
在我的情况下,我也需要添加 max-width:100%;,谢谢! - JacobTheDev
有趣的是,我使用了带有宽度、高度、视窗框和保持纵横比演示属性的SVG,而max-width: 100%会破坏其长宽比并使其宽度变小。删除max-width才是解决方法。 - steinybot

4

我在Safari浏览器中遇到了类似的问题。问题是svg的宽度和高度被渲染为dom元素属性(例如width="588.75px" height="130px")。在css中定义宽度和高度无法覆盖此尺寸设置。

要解决这个问题,在保持viewBox不变的情况下,从SVG文件中删除宽度和高度信息(可以使用任何文本编辑器编辑.svg文件)。

我的.svg文件的Git差异片段:

    xmlns:svg="http://www.w3.org/2000/svg"
    xmlns="http://www.w3.org/2000/svg"
    viewBox="0 0 588.75 130"
-   height="130"
-   width="588.75"
    xml:space="preserve"
    version="1.1"

但是,你的图像框将不会是所需的大小。它会拉伸到容器中。例如,如果您的图像宽度为100px,但容器为200px,则会填充容器,这是不合理的。 - zavr
你可以添加一个 div 包装器来正确调整 SVG 的大小。 - martin

1

0

我知道如何解决它,你只需要在你的SVG文件开头加上这个:"preserveAspectRatio="xMinYMin none",它必须放在SVG标签里面,像这样:

问题将会被解决。


2
我确定在发布这里之前已经尝试过了。纵横比并不是问题,问题在于高度的错误报告导致了麻烦。解决问题的答案是 JQuery,正如我在这里写的一样:http://www.brichards.co.uk/blog/webkit-svg-height-bug-workaround - Barry

0
我发现,如果将“position: absolute;”添加到图像元素中(如果它在父元素中也是绝对定位的),这将使我的.svg被调用,“height: 100%;”声明相对于其容器而不是页面/浏览器/设备成为可能。
我在iOS 7.1的Chrome和Safari(移动webkit)上进行了测试,并解决了我的问题(.svg文件超出了其容器)。
希望这对其他在这里遇到问题的人来说是一个比较可靠的解决方案。值得一试?

0

我在处理Javascript返回SVG的不正确“高度”值时遇到了问题,我发现解决方案就是简单地在window.load上运行我的脚本(需要访问高度的部分),而不是在document.ready上。

document.ready在DOM准备好时触发,但此时图像未必已经被渲染。当window.load触发时,图像将已经被加载(因此浏览器将能够正确访问它们的尺寸)。


0

对于你的示例,我很难理解你想要什么,或者哪些地方不符合你的意图。然而,一般来说,如果你正在使用百分比宽度和高度容器的布局,并且希望内容填充这些容器,你需要将它们从流中移除(在内容上使用position:absolute,在容器上使用position:relativeposition:absolute)。

这里有一个简单的示例,在Chrome和Safari中可以正常工作:
http://phrogz.net/SVG/size-to-fill.xhtml

#foo div 的高度和宽度是相对于 body 的百分比。它有一个红色的背景,但永远看不到,因为 SVG 是position:absolute,完全填充了它,并具有绿色的背景。如果你看到红色,那就是错误。

#foo, svg { position:absolute }
#foo { left:20%; width:30%; top:5%; height:80%; background:red; }
svg  { top:0; left:0; width:100%; height:100%;  background:green; }

<div id="foo"><svg ...></svg></div>

感谢您的回复和在示例上花费的时间。但这不是我要寻找的行为。您正在定义容器的大小,然后让SVG缩放到该大小。我需要通过SVG的大小来控制容器的大小,这就是为什么SVG高度的错误计算会搞砸一切的原因。在我的示例中,您可以看到SVG的区域,容器的宽度始终与SVG的宽度匹配,但高度完全错误;这就是为什么我认为这可能是一个错误。谢谢, 巴里 - Barry
谢谢您的澄清。所以您和SVG都有一个基于视口百分比的大小,并且将它们的容器移动到恰当的位置?我会为此创建一个示例。我不确定这与我创建的内容有何不同(最终结果),但希望它能有所帮助。 - Phrogz
我使用JQuery解决了这个问题。在window.resize事件中,我获取容器的宽度,然后运行这个公式(原始高度/原始宽度*当前宽度),这给我提供了当前SVG宽度比例下的高度,并将容器高度设置为此值。用JQuery修复渲染问题并不是很好,但是它能够工作 :) - Barry
我同意:使用脚本编写不是解决这个问题(无论是什么)的正确方法。我在你上面的问题中添加了一条评论,试图帮助你将其简化为一个简单的测试案例。如果你能清楚地表达你想要发生什么(尤其是如果你可以将其进一步简化超过我所做的),我们很可能可以在不使用JavaScript的情况下解决你的问题。 - Phrogz

0

正如先前指出的那样,WebKit对SVG的缩放最近有所改进。 在我看来,在当前的Safari(版本5.1,WebKit 534)中仍存在一些问题。 我进行了一些实验,并记录在我的网站上: http://www.vlado-do.de/svg_test/ 简而言之:在大多数情况下,在WebKit 535中使用<object>嵌入svg是有效的。 对于较旧的WebKit,我将其嵌入到<img>标记中。 如果您不想在svg内部使用链接,则这样做很好(但在较旧的Gecko中不起作用,并且在当前的Chromium中也有问题)。


0

那么这将进入Webkit夜间构建,然后进入生产环境?我希望它是一个修复,这将使生活更加轻松 :-) - Barry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接