Multicoloured icon fonts
Icon fonts are a useful and handy resource to include icons in our websites. We are all aware of the symbolic power of icons, and how they can improve user interfaces in terms of design and intuitiveness. In addition to this, icon fonts give us the possibility to style them as if they were text, so we can easily customize size, color, effects, etc, as well as improve the site performance.
We are used to icon fonts already, for instance, the Font Awesome library, the Foundation icon set or even the Umbraco icons. They are just normal fonts where characters have been replaced by custom vector shapes. We simply add them to our HTML by using tags like:
<i class="fa fa-address-book"></i>
The CSS does the rest with a rule of the type:
.fa {
font-family: Font Awesome\ 5 Pro;
}
.fa-address-book:before {
content: "\f2b9";
}
As simple as this.
Now, if we create a custom font file with custom characters we can then have our very own icon font set. The easiest way to do this is by using some online service that will generate fonts for you. I recommend icomoon.io for this purpose. It lets you choose existing icons from its multiple libraries, but it also lets you import your own icons. Then it will generate the fonts and the CSS files for you. You can even tick an option to generate SASS files.
Easy and practical, this is all we need to do:
- Design your own vector images with a graphics editor, download them from a free source or buy them.
- Use a font generator service like icomoon.io to upload your icons and generate an icon font set.
- Include the appropriate CSS files in your solution and add the icon tags in your HTML code as you need.
At Vizioz we wanted to go a bit further and I decided to explore the possibility of including multicoloured icons in the same way. I followed the same process with some nice SVG images we wanted to use on our website. The problem is that font characters cannot have more than one colour, so the resulting icons are a stack of characters on top of each other. To include them in the code we need to add some annoying extra lines that in the end tarnish the usability and simplicity of icon fonts.
<span class="v-icon-test">
<span class="path1"></span>
<span class="path2"></span>
<span class="path3"></span>
<span class="path4"></span>
<span class="path5"></span>
...
</span>
We can use some simple JavaScript methods to add all those internal layers so we don't need to worry about them and just write the outer tag in our code, or we can opt to include an SVG element which would be a great solution (maybe better?).
But there is one thing that arose my interest on sticking to the icon fonts: it is extremely easy to generate multiple different sets of icons with different color patterns (and name them with a suffix or extra class to differentiate them), by adjusting your SASS files. I think it is probably easier to understand it in the code:
@mixin iconsColorful($backgroundColor, $frontColor, $highlightColor, $suffix) {
@include iconTestColorful($backgroundColor, $frontColor, $highlightColor, $suffix);
}
@mixin iconTestColorful($backgroundColor, $frontColor, $highlightColor, $suffix) {
.v-icon-Test.#{$suffix} {
.path1 {
&:before {
content: unicode($v-icon-BusinessMail-path1);
color: $backgroundColor;;
}
}
.path2 {
&:before {
content: unicode($v-icon-BusinessMail-path2);
margin-left: $margin-left;
color: $frontColor;
}
}
.path3 {
&:before {
content: unicode($v-icon-BusinessMail-path3);
margin-left: $margin-left;
color: $highlightColor;
}
}
}
}
@include iconsColorful($background-color, $front-color, $highlight-color, "");
In this way, we can include the iconsColorful mixin as many times and with as many colour patterns as we like, and generate multiple colour pattern icons.
As stated above, we can use JavaScript to programmatically add all those internal span layers. The script will select the icon elements in our HTML and then insert the span layers needed for each element. To select the icons I used a simple jQuery selector matching the elements by class name. Then for each element selected I added a specific number of layers, depending on the name of the icon. The number of layers for each icon is also defined in the script and must correspond to the number of layers for each icon defined in our CSS.
As a reference, here is a sample of the script I used to add the path layers to the icon tags:
$(document).ready(function () {
var customIcons = {
'Test': 3
};
function addColorfulIcons(icons) {
icons.each(function() {
if (!$(this).find("[class^='path']").length) {
var className = $(this).attr("class");
var c = className.match(/v-icon-[^\s'"]+/);
var iconName = c && c[0].length > 7 ? c[0].substring(7) : undefined;
if (iconName && customIcons[iconName]) {
var layers = customIcons[iconName];
addLayers($(this), layers);
}
}
});
};
function addLayers(icon, numberOfLayers) {
for (var i = 0; i < numberOfLayers; i++) {
icon.append("<span class=\"path" + (i + 1) + "\"></span>");
}
};
function initCustomIcons() {
var icons = $("[class^='v-icon-']");
if (customIcons.length) {
addColorfulIcons(icons);
}
};
initCustomIcons();
});
We decided to build an Umbraco package using this approach, so we built a custom icon picker to use internally in our projects. Here is the final result:
I found this way of adding multicoloured icons quite fun and useful. Although debatable, I think it is an extremely interesting approach.