Lots of articles on the web compare using icon fonts to using SVGs. Published on respected sites such as CSS-Tricks and Sitepoint, some articles advocate against Icon fonts while some are in favor of them. It’s a heated debate, but the “modern” opinion seems to be that using SVG sprites is the better and more flexible option, while icon fonts are just “a hack.”
In my opinion, while SVG sprites are great and offer possibilities not seen before in terms of the ability to style and manipulate vector shapes, icon fonts still offer some advantages. At Progress, we have tried twice to use the SVG approach but have since returned to using icon fonts.
There are several ways to use SVG sprites. In this article, however, we will not consider the so-called CSS SVG sprites, due to their lack of features and enormous size (SVGs are encoded as background images in CSS files and don't support CSS interactivity such as :hover). Additionally, we won’t cover the SVG Fragment Identifiers technique; although it looks great, it has some problems, and its support in Safari and most mobile browsers is lacking.
To give you an idea of what we’re comparing, here are the two pieces of code that you need to define in the markup to show a single share in a twitter link with an icon when using SVG sprites. First you must define your icon set in the <head> tag:
<
svg
style
=
"display:none;"
>
<
symbol
id
=
"twitter-icon"
viewBox
=
"0 0 32 32"
>
<
path
d
=
"M32 6.076c-1.177 …"
fill
=
"#42c0fb"
></
path
>
</
symbol
>
<!-- remaining icons go here -->
</
svg
>
Next, you need to put this markup where you want the link to appear:
<
a
href=”#”
class
=
"twitter-icon"
>
<
svg
>
<
use
xlink:href
=
"#twitter-icon"
></
use
>
<
svg
>
Share on Twitter
</
a
>
When using an icon font you will need an additional font file, but the code to display an icon looks much simpler:
<
a
href=”#”
class
=
"twitter-icon"
>Share on Twitter</
a
>
The SVG vs Icon Font Dilemma
Although some people have been vocal about the supposedly poor accessibility of icon fonts, most of these concerns have been addressed by assigning glyphs to the Private Use Area and by an improved browser extension for dyslexics that doesn’t break icons in icon fonts. Following are two reasons why I believe icon fonts are still a viable option.
Reason 1: Size and Speed
In terms of size, icon fonts are smaller compared to SVGs, even when SVGs are compressed with gzip, as in the case of IcoMoon, SVGs can be up to 250% the size of Icon fonts, and cause a significant performance hit. For sites or applications in which speed is critical, Icon fonts may be a better choice because they are very lightweight.
Cacheable
The SVG Sprite snippet above is loaded in the HTML on every single page. And as we saw earlier, it’s big. In addition to having to load a larger icon resource, users must also download the exact same code on every different page of our website. Obviously, this is far from optimal.
An icon font, on the other hand, is a single file downloaded once that is cached; your browser won’t try to download it on every page. Instead, it loads it from the browser’s cache files and displays it instantly.
One drawback is icon fonts require an additional HTTP request, but this is insignificant if your users have browsers supporting HTTP/2. When I wrote this blog post, nearly 80% of browsers do support HTTP/2. In the event the protocol isn’t supported, the request will be loaded only once, on the first page of your site.
NOTE: SVG sprites don’t always have to be inline on the page; they can be a single external file. However, to support all browser versions, you have to include a polyfill.
Better Performance
Performance of SVG sprites once they’re loaded also lags behind that of icon fonts. This is likely because SVGs are elements in the DOM tree, and browsers seem to struggle with their repainting and manipulations once they’re on the screen. Addy Osmani, a Google Chrome engineer, has tweeted, "Also, icon font perf in Chrome is ~5x SVG atm." Other experiments show that "The frame rates were best for Font Icons and worst for inline SVGs." According to the author of this article, "Looking purely from a performance perspective, [icon fonts] seem to perform the best."
In short, if you have a graphic-rich site or app and aim for a 60 fps experience, having lots of SVG elements on the page might be a problem.
Reason 2 – Visually Appealing and Flexible
If you use icons as visual enhancements with purely ornamental purpose, you may be missing out on the flexibility they can offer. A recent article on CSS-Tricks discusses whether icons are content but misses a great feature of icon fonts: the ability to add icons to elements that match certain criteria, without writing any additional HTML markup. And, according to Designer John Hicks, “Icons are more than just pretty decorative graphics for sites and applications; they are little miracle workers. They summarize and explain actions, provide direction, offer feedback, and even break through language barriers.”
You can add icons without additional markup with icon fonts by using CSS attribute selectors, because the actual symbol information is stored in generated content. For example, it might be useful to add icons to links that point to certain file types:
a[href$=
".pdf"
]:before {...}
or to automatically mark external links as seen on David Walsh’s Blog:
a[href*=
"//"
]:not([href*=
"mysite.com"
]):before {...}
Because this method uses CSS only, it is reliable and easy to modify. To achieve the same with SVG sprites, you would have to either rely on a custom-made server-side script that changes the markup before publishing a page, or create a JavaScript function to modify the HTML on a user’s computer after the rest of the page has loaded, either of which can lead to sub-par experience.
So, Are Icon Fonts Better?
Not necessarily. The best solution depends on your use case. If you need your icons multi-colored, with shapes that can be individually changed and modified, stick with SVG sprites.
Icon fonts are a great solution for small decorative icons, because they require less effort to implement, especially if you’re using a CMS. They also provide better performance, and icons can be applied automatically to different elements with CSS attribute selectors only.
Alexander Futekov
Alexander Futekov is a Principal Front-End Developer at Progress. He has been working with web technologies for more than 6 years and loves experimenting with wacky CSS ideas. Always short on time to do what he loves - writing and speaking about his latest ideas. The few years he spent studying anthropology and working in the usability domain help him not to forget that code should be written first for people and then for machines.