It should just be an
<svg>
tag, with a<defs>
tag (which just means you are defining stuff to use later), and then a bunch of<symbol>
(group) tags. Each<symbol>
tag will have a unique ID, and will wrap all the paths and whatnot for each icon.
You need:
defs
1<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
2 <defs>
3 <symbol id="icon-facebook">
4 <!-- paths go here -->
5 </symbol>
6 <symbol id="icon-youtube"></symbol>
7 <symbol id="icon-linkedin"></symbol>
8 <symbol id="icon-mail"></symbol>
9 <symbol id="icon-whatsapp"></symbol>
10 </defs>
11</svg>
1<svg class="icon" xmlns:xlink="http://www.w3.org/1999/xlink">
2 <use href="#facebook"></use>
3</svg>
NOTE: xlink:href
is deprecated since SVG 2, you should use href
instead.
1/* Do whatever makes sense here.
2 Just know that the svg will be an
3 enormous 100% wide if you don't
4 reign in the width. */
5
6.icon {
7 display: inline-block;
8 width: 32px;
9 height: 32px;
10}
the display: none;
is there so the svg doesn’t render large amounts of empty space when the icons aren’t being rendered. by default svg renders a big empty space on the page een when it’s contents are not rendered.
The elements defined inside <symbol>
will only be rendered when they are referenced by the <use>
element.
When building the site with Parcel, you’ll get the following error and the build will fail..
Error in parsing SVG: Unbound namespace prefix: "xlink"
This is fixed by adding an xmlns:xlink
value to the <svg>
1xmlns:xlink="http://www.w3.org/1999/xlink"
have viewbox for the entire document and then specify viewbox for each icon using individual viewboxes
viewBox="x y width height"
Let’s say you have an svg file that has 5 icons (60x60 each) in a single column, with no spacing in between the icons. Your svg would become something like this
1<svg xmlns="http://www.w3.org/2000/svg" style="display: none;" viewBox="0 0 60 300"> <!-- viewBox="x y width height" -->
2 <defs>
3 <symbol id="icon-facebook" viewBox="0 0 60 60">
4 <!-- paths go here -->
5 </symbol>
6 <symbol id="icon-youtube" viewBox="0 60 60 60"></symbol>
7 <symbol id="icon-linkedin" viewBox="0 120 60 60"></symbol>
8 <symbol id="icon-mail" viewBox="0 180 60 60"></symbol>
9 <symbol id="icon-whatsapp" viewBox="0 240 60 60"></symbol>
10 </defs>
11</svg>
Since there is only one column and all the icons are right-aligned, the x
value for all icons will become 0
. The y
value is easy to calculate since all icons are of an equal height, i.e. 60px. So the first icon will begin at y="0"
and the since the second starts right after the first ends with no spacing in between, the second icon will start at y="60"
, i.e. it’s position in the file.
https://css-tricks.com/svg-fragment-identifiers-work/ https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox
1<svg class="twitter-icon">
2 <use xlink:href="path/to/icons.svg#twitter-icon"></use>
3</svg>
This xlink:href
does not work in Webkit browsers..
IE9-Edge12, Safari 5.1-6, and UCWeb 11 do not support referencing external files via
svg4everybody
also didn’t work for me on Chromium 69.0.3497.81, got svg4everybody is not defined
, failed to do anything.
xlink:href
has been deprecated in favor of href
in SVG 2. However, href
is not supported in Safari 11. It’s safe to use both for now, until SVG2 is supported by all browsers.
<svg class="twitter-icon">
<use href="path/to/icons.svg#twitter-icon" xlink:href="path/to/icons.svg#twitter-icon"></use>
</svg>
viewBox
property to crop the svg to the specific area you want. That area is what is called a fragment. A fragment identifier looks like this:#svgView(viewBox(64 0 32 32))
<img src="uiIcons.svg#svgView(viewBox(64 0 32 32))">
viewBox
values is easy if you’re using any graphic software. For example, Sketch shows the position and size values right in the top hand corner.