(live example at http://codepen.io/RwwL/pen/xbNLJp)
I'm including SVGs in an app using the <symbol>
element (see https://css-tricks.com/svg-symbol-good-choice-icons/ for full details as to why), and certain icons — ones that include clip-path
— are not rendering when I include their icons in pages with the <use>
element.
<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>
Here's how it's rendering:
It's broken in the same way across Chrome/Firefox/Safari, so it seems to most likely just be something I'm not understanding about the way other elements need to be referenced in SVG, especially when a symbol
is being pulled in via a use
. IE11 is also not rendering correctly, but in a slightly different way (no dot in the middle of the pin, but no solid square box like the others).
The problem is caused by the very first line
Removing
display: none
will render your svg referencing the inline sprite just fine.This does at first seem a bit odd since the spec tells us
But reading further down the spec it becomes apparent why setting
display: none
causes this unexpected rendering:Thus, setting
display: none
globally on thesvg
inhibits rendering of these offscreen canvases leaving you with the incomplete clip path, although it can still be referenced. Removing thedisplay
-attribute from the rootsvg
and setting it directly to theclipPath
will demonstrate the same behaviour.To hide your sprite svg you could go for something like
Update:
IE and Firefox seem to be even a bit more stringent on rendering the offscreen canvases when putting a
clipPath
inside a symbol. Since symbols itself are never rendered, the containedclipPath
will keep missing the offscreen rendering and can therefore not meaningfully be applied to any element. You should put theclipPath
right outside the symbol which works well in IE, FF and Chrome.