SVG has a very cool and powerful element called <use>
. It’s pretty simple in concept. It finds another bit of SVG code, referenced by ID, and clones it over inside the <use>
element.
The most basic use case would be: I’ve already drawn this shape(s) once on the page, and I want to draw it again someplace else. Go get that shape(s), and draw it again.
We can use that ability as the root concept for (drumroll!) and entire icon system! We can take all the shapes we intend to use on the page in one big SVG block. We’ll wrap them all in a <defs>
tag which is a semantic way to say “We’re just defining these things in which to use later.” It also makes sure they won’t render (but you should also display: none;
the <svg>
itself.
It works like this:
<svg class="icon-basketball">
<use xlink:href="#basketball"></use>
</svg>
That funky looking xlink:href
attribute references an ID elsewhere. That ID could be on a any shape element, like a <rect>
or <path>
, or it could be on a group of elements like a <g>
.
Best of all in the case of an icon system, it can be on a <symbol>
element. In addition to being correct semantically (an icon is a symbol, no?), the <symbol>
element can carry it’s own viewBox attribute and accessibility information, like <title>
and <desc>
tags. This makes the implementation very easy (as shown above).
So you just need to make sure this is defined somewhere else in the document:
<svg style="display: none;">
<defs>
<symbol id="basketball" viewBox="0 0 100 100">
<title>Basketball</title>
<path d="M28.1,3 ... "/>
</symbol>
</defs>
</svg>
See the Pen JoDmd by Chris Coyier (@chriscoyier) on CodePen.
Thanks, super useful
Great! I’m going to refer to this a lot. Question: Can I reference the icon system in an external file. Pretty sure I could do that with an include, but I’m using Joomla CMS for most of my sites.
You can!
You just need a work-around for IE because no version of it likes that. Here’s one method. And I prefer this one these days.
On Chrome is not playing nice, on :hover for example the path won’t change the fill since the original svg is someplace else. Firefox is okay with this, but Firefox has other issues though, when applying filters to svg, for no reason just blurs the svg.
Back to the 90’s web.
What about
xlink:href
being depreciated? Does that mean we can’t use this technique?https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href
Scratch that. I’ve found the relevant page.
https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use
So, presumably we just use
href
instead ofxlink:href
. Or is it worth including both for compatibility?Ah ok, you’ve covered that too:
(If you are moderating these comments, maybe just remove them :D)