Seriously, Don’t Use Icon Fonts


Icons are everywhere. These “little miracle workers” (as John Hicks described them) help us reinforce meaning in the interfaces we design and build. Their popularity in web design has never been greater; the conciseness and versatility of pictograms in particular make them a lovely fit for displays large and small.

But icons on the web have had their fair share of challenges. They were time-consuming to prepare for every intended display size and color. When high-resolution displays hit the market, icons looked particularly low-res and blocky compared to the text they often accompanied.

So it’s really no wonder that icon fonts became such a hit. Icons displayed via @font-face were resolution-independent and customizable in all the ways we expected text to be. Sure, delivering icons as a typeface was definitely a hack, but it was also useful, versatile, and maybe even a little fun.

But now we need to stop. It’s time to let icon fonts pass on to Hack Heaven, where they can frolic with table-based layouts, Bullet-Proof Rounded Corners and Scalable Inman Flash Replacements. Here’s why…

Most assistive devices will read aloud text inserted via CSS, and many of the Unicode characters icon fonts depend on are no exception. Best-case scenario, your “favorite” icon gets read aloud as “black favorite star.” Worse-case scenario, it’s read as “unpronounceable” or skipped entirely.

Screenshot of icon issue after replacing fonts on GitHub

Many dyslexic people find it helpful to swap out a website’s typeface for something like OpenDyslexic. But icon fonts get replaced as well, which makes for a frustratingly broken experience.

Most of the time, we rely on automated tools to choose which Unicode characters are assigned to which icon. But Unicode’s also where our beloved emoji live. If you aren’t careful, they can overlap in confusing (albeit hilarious) ways. My favorite example: Etsy’s “four stars and a horse” bug. More recently, our own Jason Grigsby encountered random fist-bumps on ESPN’s site.

Microsoft's example missing glyph characters

When your icon font fails, the browser treats it like any other font and replaces it with a fallback. Best-case scenario, you’ve chosen your fallback characters carefully and something weird-looking but communicative still loads. Worse-case scenario (and far more often), the user sees something completely incongruous, usually the dreaded “missing character” glyph.

Custom fonts shouldn’t be mission-critical assets. They fail all the time. One look at Bootstrap’s icon-related issues and it’s no wonder why they’re removing them entirely from the next version.

Worse still, many users will never see those fonts. Opera Mini, which frequently rivals iOS Safari in global usage statistics with hundreds of millions of users worldwide, does not support @font-face in most cases. Opera recommends avoiding icon fonts if you want to support Opera Mini.

Detail of Stackicons' octocat in IE11

The way browsers hint fonts to optimize legibility was never a good fit for our custom iconography, and support for tweaking that behavior is all over the place.

Multicolor icons are even worse. The technique of overlaying multiple glyphs to achieve the effect is impressively resourceful, but the results often look like their printing registration is misaligned.

“But Tyler,” I hear you say. “You’ve completely ignored Filament Group’s Bulletproof Icon Fonts, complete with feature tests and sensible, content-driven fallback solutions.”

And you’re right. Those techniques are great! If you’re using an icon font, you should definitely follow their recommendations to the letter.

But you probably won’t.

What you’ll probably do is adopt whatever your framework of choice has bundled, or drop in some massive free icon font you can use right away. You won’t modify how they work out of the box because that’s really hard to prioritize, especially when they look great on your monitor with virtually no effort at all.

Or maybe you will do the work, designing and curating a custom icon font, choosing your Unicode characters carefully, documenting and evangelizing the importance of implementing your icons in an accessible way with appropriate fallbacks. Then one day, Dave forgets to add a fallback image to that iconographic button he added (which looks great, by the way), which Roberta reuses for her related Pull Request, and before you know it, your app has devolved into a fragile, hack-littered wasteland once more.

These examples are not hypothetical (though names have been changed to protect the innocent). I’ve seen them happen to multiple organizations, all of them starting with the best possible intentions.

SVG is awesome for icons! It’s a vector image format with optional support for CSS, JavaScript, reusability, accessibility and a bunch more. It was made for this sort of thing.

But I hear a lot of excuses for why teams avoid using it, even for brand-new projects. Here are a few…

They totally can. There are even really great tools like svg-sprite and IcoMoon that can help automate that process.

Usually when I hear this, the team’s comparing a single binary icon font to multiple, uncompressed SVG files. The gap narrows dramatically when you optimize your SVGs, combine reusable ones into sprites, and deliver those with active Gzip compression or embedded in-page.

Occasionally I’ve heard the gap is still too wide when hundreds of icons are included. This begs the question: Why are you including hundreds of icons on every page?

Let’s compare:

<!-- Typical @font-face icon: -->
<span class="icon icon-search" aria-hidden="true"></span> <!-- Typical SVG icon: -->
<svg class="icon"> <use xlink:href="path/to/icons.svg#search"/>
</svg>

The SVG markup is barely more verbose, and way more descriptive and semantic than some empty, ARIA-hidden <span> element.

As of this writing, global support for SVG is up to 96%… 4% higher than the same stat for @font-face. Plus, SVGs are way more accessible and their fallbacks are much more straightforward.

If your framework told you to jump off a bridge, would you?

I was in school when the Web Standards movement hit critical mass. While the majority of my instructors saw the merits of semantic markup and embraced it wholeheartedly, one passionately held out. “Table Guy” argued that no layout tool could usurp <table>, that it was inherently better-suited for crafting grid-based designs. He boasted of how quickly and easily he could achieve the “Holy Grail” layout with his trusty table cells. He cited the wealth of cross-browser inconsistencies that continued to plague CSS.

Table Guy and I kept in touch. Today, he freely admits he was wrong about CSS. He feels embarrassed to have been so married to a technique that was so clearly misappropriated in hindsight.

If you won’t stop using icon fonts for people with screen readers, people with dyslexia, people with browsers that don’t support @font-face, people who randomly didn’t load the icon font once for some reason, or designers who just want their icons to look right on-screen…

Then do it for yourself. Don’t be Table Guy.