Ravn Webveveriet logo

Fragmentation and scalability

There are many ways to display icons on a website today, some more modern than others. Take for instance version 5 of Font Awesome which proposes three different methods; SVG with javascript, icon fonts and SVG sprites. All of these implementations come with their own sets off pros and cons. In this article-series we will present different methods of implementation related to a specific use case, i.e. handling multiple external icon-sets.

We wanted to experiment with font icons for this article because we use them daily and they are usually a good fit for our practical needs and current system. This is part one of the article series, in which we will present one implementation of icon fonts.

SCSS, fagprat introbilde

SCSS Multiple Icon Sets

We will start by reviewing the common pros and cons of icon fonts.

Pros:

  • They can be easily scaled.
  • Good cross-browser compatibility when utilising the different formats.
  • Easy to work with.


Cons:

  • Accessibility concerns because they are invisible to screen readers.
  • Rendering issues due to the fact that icon font is text and not vector graphics

By using icons from different sources, common problems are fragmentation and scalability. For this article example we want to present icons from three independent sources — Font awesome, Material Icons from Google and Material Design Icons from the community. The ideal situation for us was to be able to reference the icons the same way regardless of the source — so we created a sass map where we stored all the unicodes we were going to use.

$icons: (
fa: "\f2b4",
md: "\E859",
mdc: "\F036"
);


Three variables were declared, one for each font-family.

$fa-family-brands: 'Font Awesome 5 Brands';
$md-family-default: 'Material Icons';
$mdc-family-deafult: 'Material Design Icons';


We created one sass mixin that would take four arguments:

  • Position — before, after or both
  • Font family — to be able to use icons from the different sources.
  • Icon name — which stored the unicode for the icon
  • Styles — default styles for the icons with possibility to add more styles in different contexts


@mixin icon($position: before, $font-family: true, $icon: false, $styles: true) { 
@if $position == both {
$position: 'before, &:after';
}
// Either :before or :after pseudo-element, or both, default is :before
&:#{$position} {
@if $icon {
content: "#{map-get($icons, $icon)}";
}
@if $styles {
display: inline-block;
font: normal normal normal $icon-size/1 '#{$font-family}';
font-size: inherit;
text-rendering: auto;
line-height: inherit;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
@content;
}
}


In the end all we had to do was include the mixin with the arguments where we wanted to show an icon.

.comp-1{
@include icon(after, $fa-family-brands, fa);
}


You can take a look at the full-example here: https://codepen.io/mmoverla/pen/ypBjBw

This approach is easily scalable if we want to add more icon-sets in the future. It is easy to swap icons with little effort, by changing the unciode in the sass map and/or changing the arguments where you are calling the mixin. One problem with this implementation is that accesibility suffers, a problem we will need to address in the future.

For our next project we will take what we have learned from this approach and apply it to make a svg-sprite system — stay tuned.

30.08.2018