在SVG精灵中,剪切路径(clip-path)无法正常工作

4
(live example at http://codepen.io/RwwL/pen/xbNLJp)
我在应用程序中使用<symbol>元素包含SVGs(查看https://css-tricks.com/svg-symbol-good-choice-icons/了解详细信息),但是当我使用<use>元素在页面上包含一些包含clip-path的图标时,这些图标不会被呈现。请帮忙检查问题所在并提供建议。
<svg style="display: none">
  <symbol id="icon-pin" viewBox="0 0 24 24" enable-background="new 0 0 24 24">
    <path fill="none" stroke="#2F3137" stroke-width="2" stroke-miterlimit="10" d="M12 2C8.3 2 5.3 5 5.3 8.7c0 1.2.3 2.3.9 3.3l5.4 9.9c.1.1.2.2.4.2.1 0 .3-.1.4-.2l5.4-9.9c.5-.9.9-2.1.9-3.3C18.7 5 15.7 2 12 2zm0 0" />
    <clipPath id="pin-clip">
        <path d="M12 11.2c-1.4 0-2.5-1.1-2.5-2.5s1.1-2.5 2.5-2.5 2.5 1.1 2.5 2.5-1.1 2.5-2.5 2.5zm0 0" />
    </clipPath>
    <path clip-path="url(#pin-clip)" fill="#2F3137" d="M4.5 1.2h15v15h-15z" />
  </symbol>
</svg>
</div>

<h2>Normal inline SVG</h2>
<svg id="inlinePin" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24" enable-background="new 0 0 24 24">
    <path fill="none" stroke="#2F3137" stroke-width="2" stroke-miterlimit="10" d="M12 2C8.3 2 5.3 5 5.3 8.7c0 1.2.3 2.3.9 3.3l5.4 9.9c.1.1.2.2.4.2.1 0 .3-.1.4-.2l5.4-9.9c.5-.9.9-2.1.9-3.3C18.7 5 15.7 2 12 2zm0 0" />
    <clipPath id="inline-pin-clip">
        <path d="M12 11.2c-1.4 0-2.5-1.1-2.5-2.5s1.1-2.5 2.5-2.5 2.5 1.1 2.5 2.5-1.1 2.5-2.5 2.5zm0 0" />
    </clipPath>
    <path clip-path="url(#inline-pin-clip)" fill="#2F3137" d="M4.5 1.2h15v15h-15z" />
</svg>

<h2>Inline SVG using sprite</h2>
<svg>
  <use xlink:href="#icon-pin">
</svg>

这是它的呈现方式: enter image description here 在Chrome/Firefox/Safari中都以相同的方式破碎,因此最有可能的是我对SVG中其他元素引用方式的理解有误,特别是当通过"use"来拉入"symbol"时。 IE11也无法正确呈现,但方式略有不同(没有图钉中间的点,但没有像其他浏览器那样的实心正方形框)。
1个回答

5
问题是由第一行代码引起的。
<svg style="display: none">

去掉display: none属性将会正确渲染您的svg内联sprite引用。
这似乎有点奇怪,因为规范告诉我们:

‘display’属性不适用于‘symbol’元素; 因此, 即使将‘display’属性设置为none时,‘symbol’元素也不会被直接渲染,并且即使在‘symbol’元素或其任何祖先的‘display’属性设置为none时,‘symbol’元素也可用于引用。

但是读规范中的进一步内容后,就可以看出为什么设置display: none会导致这种意外的渲染:

‘display’属性还影响直接渲染到屏幕以外画布上[...]在‘clipPath’元素的子元素上设置display:none将阻止给定的子元素对剪裁路径的贡献。

因此,在svg全局设置display: none会抑制这些屏幕外画布的渲染,使您只得到不完整的剪辑路径,尽管仍然可以引用它。从根svg中删除display属性并将其直接设置为clipPath会展示相同的行为。
要隐藏您的sprite svg,您可以选择以下样式:
<svg width="0" height="0">

更新:

在将clipPath放置在符号内部时,IE和Firefox似乎更加严格地呈现屏幕外Canvas。由于符号本身从未被呈现,所包含的clipPath将始终缺少屏幕外渲染,因此无法有意义地应用于任何元素。您应该将clipPath放在符号的外部,这在IE、FF和Chrome上都可以很好地工作。

<svg>
    <clipPath id="pin-clip">
        <path d="M12 11.2c-1.4 0-2.5-1.1-2.5-2.5s1.1-2.5 2.5-2.5 2.5 1.1 2.5 2.5-1.1 2.5-2.5 2.5zm0 0" />
    </clipPath>
    <symbol id="icon-pin" viewBox="0 0 24 24" enable-background="new 0 0 24 24">
        <path fill="none" stroke="#2F3137" stroke-width="2" stroke-miterlimit="10" d="M12 2C8.3 2 5.3 5 5.3 8.7c0 1.2.3 2.3.9 3.3l5.4 9.9c.1.1.2.2.4.2.1 0 .3-.1.4-.2l5.4-9.9c.5-.9.9-2.1.9-3.3C18.7 5 15.7 2 12 2zm0 0" />
        <path clip-path="url(#pin-clip)" fill="#2F3137" d="M4.5 1.2h15v15h-15z" />
    </symbol>
</svg>

谢谢,非常有趣的解决方案。在Chrome/Firefox/Safari中删除display: none可以很好地解决这个问题,但是IE10/11仍然存在相同的问题;你有什么想法吗? - RwwL
IE和FF似乎对此更为严格。我在我的答案中加入了一个更新,涉及IE、FF和Chrome。 - altocumulus
太棒了。这是原始代码的跨浏览器解决方案分支:http://codepen.io/RwwL/pen/GgaGgV 非常感谢!重构我们库中一些图标会很麻烦,但至少它能工作...再次感谢! - RwwL
截至2016年3月21日,Chrome 48.0.2564.116(64位)似乎只能支持内联SVG。:( - Lesha Ogonkov
与什么相反?您能提供一个演示,展示您遇到的问题吗? - altocumulus

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