通过 webapp 提供时,SVG 片段标识符在 Safari 中被交换

Posted

技术标签:

【中文标题】通过 webapp 提供时,SVG 片段标识符在 Safari 中被交换【英文标题】:SVG fragment identifiers are swapped in Safari when served through webapp 【发布时间】:2015-12-13 21:40:45 【问题描述】:

我在下面的简单示例中复制了我的问题

我有一个简单的网页,如下所示:

<html>
    <head></head>
    <body>  
        <img src="icons.svg#close"></img>
        <br>
        <img src="icons.svg#error"></img>
    </body>
</html>

在 Safari 本地查看此页面,页面正确呈现:

关闭图标出现在错误图标上方的位置。


但是,当我使用 NodeJS webapp 提供文件(或使用 python SimpleHTTPServer 命令)并在 Safari 中查看它时,图像在彼此的位置:

即使 dom 看起来仍然正确,并且每个 img 标记的 src 属性包含正确的路径。


这是icons.svg 文件:

<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <style>:root>svgdisplay:none:root>svg:targetdisplay:block</style>
    <svg viewBox="0 0 12 12" enable-background="new 0 0 12 12" id="close">
        <path d="M7.2 6l4.5-4.4c.4-.4.4-.9 0-1.3s-.9-.4-1.3 0L6 4.7 1.6.3C1.2-.1.7-.1.3.3s-.4.9 0 1.3L4.7 6 .3 10.4c-.4.4-.4.9 0 1.3.2.2.4.3.6.3s.5-.1.7-.3L6 7.3l4.4 4.4c.2.2.4.3.7.3.2 0 .5-.1.7-.3.4-.4.4-.9 0-1.3L7.2 6z" opacity=".3" enable-background="new"/>
    </svg>
    <svg viewBox="0 0 58 46" enable-background="new 0 0 58 46" id="error">
        <style type="text/css">.st0fill:#ff9141.st1fill:#fff</style>
        <path class="st0" d="M30.6 1c-.9-1.4-2.3-1.4-3.2 0L.4 43.5C-.5 44.9.2 46 1.8 46h54.4c1.7 0 2.3-1.1 1.4-2.5L30.6 1z"/>
        <path class="st1" d="M26.3 15.2h5.5V30h-5.5zM26.3 33.5h5.5v5.3h-5.5z"/>
    </svg>
</svg>

无论文件是在本地加载还是通过服务器提供,页面都能在所有其他浏览器中正确呈现。

【问题讨论】:

非常非常奇怪。当从 Apache 网络服务器访问文件时,我也会遇到相同的行为。 我尝试了几个可用的网络服务器,但我无法重现这种行为。可能是因为您的网络服务器没有按时提供 icons.svg 文件,所以浏览器决定不等待并尝试下一个图标然后 svg 可用? 如果没有 Safari 进行测试,也可能是 HTTP 标头 Content-Type 问题。 @tyler 你试过 Safari 9 吗?情况似乎变得更糟 - :target 似乎什么都不做(从不匹配),我在答案中链接到的测试页面给出了不同的错误结果,除了使用 background-imagebackground-position 的 svg,现在看来是正确的 我没有在 Safari 9 中尝试过。感谢您提及。 【参考方案1】:

这是由于 Safari 中的 SVG 片段 CSS 支持不完整/有问题。浏览器对该技术的支持仍然相对不完整 - 请参阅 https://css-tricks.com/svg-fragment-identifiers-work/

当前版本的 Chrome/Safari/Opera (38/8/25) 可以很好地处理所有 HTML 技术,但没有任何 CSS 技术,包括背景位置技术。

这是我的 Safari 8(左)和 Chrome(右)呈现测试页面的方式 - 请注意,图标应该每次都转到 :

对您的内容进行了一些实验:

如果我第二次重复这对图像,第四张图像在某种程度上是两者的合成(左下)。对您的 svg 的任何解释都不应该能够产生这样的图像。有趣的是,如果您使用不同的样式属性,我会得到完全相同的拆分,例如不透明度(右下):

如果我用 cmd++cmd+- 放大和缩小,重叠和部分图像变化。

调整页面大小也有效果。

推测图像的样式可能会以某种方式相互交互,我尝试拥有四个不同的图像副本(icons1.svg#closeicons2.svg#error 等)并分别引用它们。这主要解决了问题,但第四张图片缺少底部四分之三。但是,当我调整窗口大小时,图像的缺失部分出现了。

底线:不完整/错误的 svg 片段标识符/CSS 处理。

【讨论】:

以上是关于通过 webapp 提供时,SVG 片段标识符在 Safari 中被交换的主要内容,如果未能解决你的问题,请参考以下文章

text 使用SVG的片段

跨域访问方法介绍--使用片段识别符传值

使SVG linearGradient遵循路径

css 快速片段将svg与中心对齐并缩放到视口大小。

如何通过 jnlp 提供带有许多 webapps 的码头?

从 AngularJS url 中删除片段标识符(# 符号)