【发布时间】:2015-04-30 13:20:15
【问题描述】:
我正在尝试使用 SVG stacking technique 来启用多个图标堆叠在一个文件中,只需要来自浏览器的一个 HTTP 请求。该技术在here 进行了相当详尽的描述。
基本上这个想法是将多个 SVG 元素放入一个 SVG 文件中,并使用 CSS 样式隐藏所有图标,除了您当前要显示的图标。使用 CSS :target 选择器选择当前要显示的图标。
该技术对我有用,除了堆叠多个图标会导致显示的图标出现奇怪的扭曲,即使所有其他图标都被隐藏了。
在我正在使用的示例中,我将其简化为仅堆叠 两个 图标:一个美国国旗图标和一个英国国旗图标。
(简化的)SVG 文件是:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg id="svg153" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="480" width="640" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">
<svg:style
xmlns:svg="http://www.w3.org/2000/svg" type="text/css">
.i { display: none; }
.i:target { display: block; }
</svg:style>
<svg:svg id="uk" xmlns:svg="http://www.w3.org/2000/svg" class = "i" height="480" width="640" version="1.1">
<!-- SVG elements to draw UK flag -->
</svg:svg>
<svg:svg id="us" xmlns:svg="http://www.w3.org/2000/svg" class = "i" height="480" width="640" version="1.1">
<!-- SVG elements to draw US flag -->
</svg:svg>
</svg>
请注意,CSS 嵌入在 SVG 文件中的 <svg::style> 元素中。 CSS 很简单:
.i { display: none; }
.i:target { display: block; }
这样,任何带有class="i" 的svg::svg 元素都会自动不可见,除非我们在SVG url 中专门定位它。因此,要显示美国国旗图标,我将使用以下 HTML sn-p:
<img
src="flags.svg#us"
width="80"
height="60"
alt="SVG Stacked Image"
/>
当然,要显示英国国旗,我会将其更改为 src="flags.svg#uk"
无论如何,所有这些都非常有效......除了当我堆叠图像时在 Firefox 和 Chrome 中都会出现奇怪的图像失真。
这是我从 SVG 文件中删除(隐藏的)英国国旗时美国国旗的屏幕截图:
如您所见,它看起来不错。
但是当我把它堆在英国国旗前时,它看起来像:
如您所见,图像变得异常扭曲 - 当您在压缩图像中获得大量“伪像”时,它几乎看起来像低质量 JPEG 所发生的情况。
那么究竟为什么会发生这种情况?与美国国旗图标堆叠的其他图像都是不可见的,那么为什么它们会影响可见的图标呢?
我在 Google 上四处寻找答案,虽然 SVG 堆叠技术肯定存在许多问题和“陷阱”,但它们都与跨浏览器兼容性有关。但是,该技术在大多数更新的浏览器(包括 IE9)上都可以正常工作。此外,Firefox 和 Chrome 都会出现失真,因此这不太可能是跨浏览器的问题,而是我做错了。
那么,当我应用 SVG 堆叠技术时,是什么导致了这种奇怪的失真?
【问题讨论】:
-
你能提供一个Fiddle吗?
-
使用不透明度与显示效果是否相同?
-
如果有完整的代码来玩它会很好(也许看看你是否可以用一个非常基本的条纹图标获得相同的效果)。但是,查看您的屏幕截图,它似乎与抗锯齿有关:浏览器正在组合抗锯齿像素的颜色,并且在移除背景时没有正确地重新绘制它们。出于您的目的,一些建议:将白色条纹绘制为不透明的白色(或为旗帜绘制白色背景)或设置
shape-rendering: cripsEdges。但这是错误的行为,我很惊讶它在 Chrome 和 Firefox 中都是一个问题。 -
为什么不将它们分成两个不同的 svg 文件。将它们放在一个 div 中。并通过绝对定位将它们相互对齐?要么是浏览器,要么是因为背景较暗而显示的文件。
-
Boris,这里的重点是节省浏览器请求并且只使用一个 SVG 文件。分开会破坏目的。