Blog

This is about web development and nagios monitoring.

Switch from Icon Fonts to SVG Icons (example with Font Awesome)

Written from Klement

We recently switched from Icon Fonts to SVG Icons. If you stumbled upon this article you may already like to do the switch as well. If you aren't convinced head over to CSS Tricks to get a nice comparison list. The main reason for us was that we had problems when using HTTPS and Internet Explorer within a Citrix environment (and some workarounds didn't work quite well).

So we are using Font Awesome and like to use the same font library with SVG. This tutorial will show an easy way to convert all your icons to an SVG sprite and ditching Font Icons. I will show that along a little example with a menu structure and a some CSS styling.

Updated 2018-05-29:
FontAwesome offers native SVG support in their latest release. So this article is only relevant if you use the old FontAwesome v4.

1. Create a SVG sprite

With Font Icons you have a font with all icons included in one file and choose which icon we want to display within the code. We want to have the same behavior with SVG icons so we need to create a sprite that has all SVG icons in one file. Font Awesome doesn't offer such a download so a neat way of doing this is to use IcoMoon. They offer a lot of free font libraries but for the purpose of this tutorial we like to use Font Awesome. So head over to the IcoMoon App and follow these steps:

a) Add the library you like to use

b) Select the icons you want to have in the sprite (for simplicity we just take all icons)

c) Click the bottom tab to switch the view for actual generating the sprite

d) We can customize the download a little bit by clicking the settings wheel.

Now download the file and extract this ZIP file somewhere on your system. If you need to add the SVG sprite map creation to your build process you could also use a Grunt plugin like SVG-Sprite. I don't cover the use of this plugin in this article, though.

 

2. What files do I need from that ZIP?

If you don't care about Internet Explorer support you just need "symbol-defs.svg". But if you also like to show the icons to Internet Explorer users you also need the file "svgxuse.js". Normally SVG is supported from IE 9+ but the way we like to load the SVGs with a sprite map isn't possible including IE 11.

So place the files like that for example:

assets/images/symbol-defs.svg
assets/js/svgxuse.js

 

3. How do I load the SVG icon?

The simplest way is:

<svg><use xlink:href="assets/images/symbol-defs.svg#icon-home"></use></svg>

So we have the path of the sprite map directly in the xlink:href attribute of the "use" element. This is a really cool way to load a specific SVG without the need for inline SVG. Now you should see a big black house icon. You can look up the icon names in the demo.html that came with the IcoMoon ZIP file. But they are the same like the Font Icon names. So if you used "fa-home" you now use "icon-home". While generating the sprite map you could have also use the same "fa-" prefix.

 

4. What's about styling, links and hover effects?

The styling works a little bit different with SVG icons than Font Icon CSS. So I'll give an example with a simple menu structure:

For example you have to use the CSS style "fill" to give the icon another color compared to "color" with a font icon. So let's build the exact same menu with Font Icons and then with SVG icons.

 

4.1. Menu example: Font Icons

index.html

<!DOCTYPE html>
<html>
<head>
	<link rel="stylesheet" href="assets/styles/font-awesome.css">
	<link rel="stylesheet" href="assets/styles/menu.css">
</head>
<body>

	<ul id="menu">

		<li>
			<a href="index.html">
				<span class="icon-menu fa fa-home"></span> Item 1</a></li>
			</a>
		</li>

		<li>
			<a href="index.html">
				<span class="icon-menu fa fa-search"></span> Item 2</a></li>
			</a>
		</li>
		
		<li>
			<a href="index.html">
				<span class="icon-menu fa fa-cog"></span> Item 3</a></li>
			</a>
		</li>
		
	</ul>

</body>
</html>

I use the class "icon-menu" to style the icon.

menu.css

.icon-menu
{
	width: 24px;
	padding: 4px 2px 4px 2px;
	text-align: center;
}

#menu {
	list-style-type: none; 
}

#menu a {
	display: block;
	width: 245px; 
	font-family: Verdana;
	font-size: 11pt;
	text-decoration: none;
	color: #555555;
	background-color: #F0F0F0;
	margin: 3px;
	padding: 1px 0px 1px 3px;
}

#menu a:hover {
	background-color: #556670;
	color: #F5F5F5;
}

 

We have the hover selector to change background color and font color. This will change the text and the icon itself (since it behaves like a font and is inside the anchor element).

 

4.2. Menu example: SVG Icons

index.html

<!DOCTYPE html>
<html>
<head>
	<link rel="stylesheet" href="assets/styles/menu.css">
	<script src="assets/js/svgxuse.js" defer></script>
</head>
<body>

	<ul id="menu">

		<li>
			<a href="index.html">
				<svg class="icon icon-menu"><use xlink:href="assets/images/symbol-defs.svg#icon-home"></use></svg> Item 1
			</a>
		</li>

		<li>
			<a href="index.html">
				<svg class="icon icon-menu"><use xlink:href="assets/images/symbol-defs.svg#icon-search"></use></svg> Item 2
			</a>
		</li>
		
		<li>
			<a href="index.html">
				<svg class="icon icon-menu"><use xlink:href="assets/images/symbol-defs.svg#icon-cog"></use></svg> Item 3
			</a>
		</li>
		
	</ul>

</body>
</html>

As mentioned before we need the JS file "svgxuse.js" for IE compatibilty. To style the icon I use the two classed "icon" and "icon-menu".

menu.css

.icon {
	width: 1em;
	height: 1em;
}

.icon-menu {
	fill: #555555;
	vertical-align: middle;
	padding: 0px 6px 4px 6px;
}

#menu {
	list-style-type: none; 
}

#menu a {
	display: block;
	width: 245px; 
	font-family: Verdana;
	font-size: 11pt;
	text-decoration: none;
	color: #555555;
	background-color: #F0F0F0;
	margin: 3px;
	padding: 1px 0px 1px 3px;
}

#menu a:hover {
	background-color: #556670;
	color: #F5F5F5;
}
#menu a:hover .icon-menu {
	fill: #F5F5F5;
}

Without a width and height the icon would be really big. No matter how you style the font size from the surrounding element. So giving 1em as height and width is a good way to have the icon the same size as the font size. If you like different sizes depending on where to place the icons just overwrite the styles.

The next difference is the "hover" selector. We can't just add "fill" to a:hover. This won't affect the SVG. So you need to add the class name of the SVG element (or use the svg element itself).

 

I hope that article helped you to switch your Font Awesome Icon Fonts over to SVG. There are a lot of things that you can do with SVGs so that was just to get you started.