Pictos

Using Icon Fonts

Updated: January 26th 2012

This article is to serve as a guide for best practices when using icon fonts on the web. Because icon fonts are still in their infancy, browser support and new technologies are constantly being developed. Be sure to check back often for updated information. If you have any knowledge or experience to contribute, please tweet to @pictos or email drew@pictos.cc to have it included in this article.


What Are Icon Fonts

In this article Icon Fonts refers to using the @font-face rule in CSS to embed TTF, EOT and similar font formats into a web page. This is not an article about Cufón sIFR or any other method.

The entire purpose of using icon fonts is to replace the need to render icons on a web page using images. Icons fonts can be styled dynamically using CSS. They are smaller in file size than an image sprite. Being vector in nature, they are infinitely scaleable.


Accessibility

Yes, icon fonts are 100% accessible. For a piece of content to be accessible it requires that any user can access that content. This is true with icon fonts. The issue lies in how that content is interpreted by the browser. If you were to map a cloud icon to the letter "C" on your keyboard in your icon font, the browser would interpret the icon as the letter "C"; not a cloud. The issue is not "is the icon accessible?", the issue is "is the icon interpreted correctly?".

All web developers have been faced with this issue daily when: adding images to a web page. Images face similar issues of "accessibility" or "browser interpretation". A browser has no way of knowing what any image represents or means. Just like icon fonts. To combat this, the HTML lords gave us attributes like alt and title. In fact, you MUST specify an alt attribute on images in order for it to validate as HTML. Images in HTML have been around so long that all major browsers know to check the alt attribute to get the meaning of the image. Screen readers use it as well to describe the image to the user. Browsers are smart enough to not to read aloud the binary from the image.

Icon fonts being in their infancy means we are at the beginning. Icon fonts are a better way in all aspects over images to render icons to a webpage. The only exception could be "crispness" or "quality of rendering" on older browsers (read as: older IEs). But that is an issue of vanity and opinion, not execution. Flat icons are extraordinarily common on both the web and mobile/desktop operating systems. They are not going anywhere. We need HTML and/or CSS to accommodate for icon fonts (you'll see they already have, in spec but not in practice). For now, there are other ways around the "interpretation issue", we'll take a look at those now.


Embedding the Font

The original Pictos Font was released in August of 2010. It quickly gained popularity and with that came experimentation on how to embed it into a web page. One of those was a project by @simurai done as an entry to a contest I held for the Pictos Font. This was the first time I saw the "data insertion" method in use. I immediately adopted it for the Pictos Font. It still remains the best method for embedding icons into your web page.

Here is an example inserting a cloud icon, mapped to the letter "C", into an anchor tag.

HTML:

<a href="" data-icon="C">Cool Link</a>

CSS:

[data-icon]:before {
	font-family: 'Pictos Custom';
	content: attr(data-icon);
}

Result: Cool Link

Using the :before selector in CSS you can insert the cloud icon before the anchor text: "Cool Link". Similarly, you can also use the :after selector to insert the icon after the text. More on those selectors here.

In the CSS above we are selecting any element with an attribute of "data-icon". We are then telling it to use the "Pictos Custom" font and telling it to insert the value of the "data-icon" attribute in our HTML into that element. Which means "C" gets placed into the element.
Alternatively you can use a class based selection if you prefer:

HTML:

<a href="" class="icon" data-icon="C">Cool Link</a>

CSS:

.icon:before {
	font-family: 'Pictos Custom';
	content: attr(data-icon);
}

Inserting the "C" character into the HTML using CSS means we get clean HTML code. There will be no random charcters floating around in your HTML causing confusion. This is great for when your web page is scraped or read by a program, they will not see the "C" anywhere. Unfortunately inserting with CSS adds the character to the Shadow DOM meaning a screen reader will pick it up and read the "C" aloud. This can possibly cause some confusion, but in my tests it does not break the experience. You literally just hear "C Cool Link". I have personally tested this on VoiceOver for Mac, NVDA on my PC laptop and others. Having a random character read aloud is obviously not ideal or anything we should settle for.

As I mentioned before, the CSS & HTML specs have already built in support for icon fonts, it's just a matter of time for all browsers (including screen readers) to adopt the new additions. The support for icon fonts comes in the form of the aria attributes in HTML and the speak property in CSS.

Eric Eggert has written a great article about this very subject. By simply applying aria-hidden="true" to your HTML element you can avoid having your icon read aloud. Eric even gives a tiny jQuery function to do all this automatically.

My example below is slightly different than Eric's in that I use the CSS insertion method to put the letter "C" into the span element. This keeps the HTML clean and keeps the "C" hidden from programs and scrapers.

HTML

<a href="">
	<span aria-hidden="true" data-icon="C"></span>
	Cool Link
</a>

CSS:

[data-icon]:before {
	font-family: 'Pictos Custom';
	content: attr(data-icon);
}

In the case of "the lone icon", where you display an icon all by itself without any other inline text (ie. a nav bar), there is no descriptive text for the browser to fallback on. That's not really a big deal, since the solution is quite simple. Just wrap the descriptive text in an element and hide it from the page using CSS. When a program/scraper comes along, they will see the descriptive text ONLY and all is well. When a screen reader reads the page, they will also see and read alond the descriptive text, just as it should be.

HTML

<a href="">
	<span aria-hidden="true" data-icon="C"></span>
	<strong>Cloud Page</strong>
</a>

CSS:

[data-icon]:before {
	font-family: 'Pictos Custom';
	content: attr(data-icon);
}

strong {
	text-indent: -99999px;
}

Result: Cloud Page

The result is a standalong icon that when accessed by a program/scaper or screen reader, will read: "Cloud Page". Alternatively, you could simply put an alt attribute on the <a> (anchor) tag with a value of: "Cloud Page".


Enhancing the Pretties

To make the icons look their best there are a few simple things you can do. For webkit, apply the following rule: -webkit-font-smoothing: antialiased; This makes your icons look drastically better and the best part is it's webkit, so that covers most mobile browsers as well. The result would look like:

[data-icon]:before {
	font-family: 'Pictos Custom';
	content: attr(data-icon);
	-webkit-font-smoothing: antialiased;
}

When using icon fonts inline with other text the vertical-align property in CSS is your friend. You can play with it's values to get your font to be centered with the rest of the text. Typically, just adding vertical-align: middle; to the above block of CSS code is all you need when displaying icons inline with other text.


Unicode

One thought that exists regarding icon fonts and best practices is to map the icons to their appropriate unicode characters. This is a great idea and can be done using the Pictos Server by pasting in the unicode character you want to map to into the font builder. However, simply mapping icons to unicode characters it is not a complete fix since there are cases when an icon may not have a matching pair in unicode. However, there are 100s of thousands of unassigned code points in unicode, that might help.

In unicode, groups of code points are called "planes". There are 2 planes called Supplementary Private Use Area A & B (PUA), which are made up of code points that will NOT be read by screen readers. From Wikipedia:

The two planes 15 and 16, called Supplementary Private Use Area-A and -B (or simply Private Use Area (PUA)) are available for character assignment by parties outside the ISO and the Unicode Consortium. They are used by fonts internally to refer to auxiliary glyphs, for example, ligatures and building blocks for other glyphs. Such characters will have limited interoperability. Software and fonts that support Unicode will not necessarily support character assignments by other parties.

These unicode code points present the best possible solution for achieving unicode conformity. @keyamoon has great example and video of this in action. Notice the screen reader does NOT read the icon font aloud.


A Little Perspective

As for icon fonts being "too harmful" to use at the present time, that is simply not true. Developers currently use technologies that are "inaccessible" all the time: flash, canvas, svg, image maps (lol). That doesn't make it OK to use inaccessible technology, but in the case of icon fonts it certainly is not harmful to anyone at all. The use of Canvas and SVG are regarded as "just fine", but typically contain elements that users interact with (graph, chart, table) while having no way to provide a representation of that content to screen readers, programs or any browser/user that cannot physically see whats on the screen (more). Icon fonts contain presentational content that never will hold vital or necessary information. If someone can't see an icon from a font, it's just the same as if that person can't see an image icon. Unlike a canvas based graph or chart.

Icon fonts are a great idea and will save time for developers and designers. Use them now and the web will adapt and adopt them.

All icons Below are the Pictos Font. There are no images.

Using the Pictos Font and CSS3 you can make some awesome & lightweight toolbars.
Try clicking the icons. View in Webkit for best results. Zero images used.

Complex lighting, shadowing and gradient effects made possible by CSS3.
Try hovering over this area.

Since it is just a normal font, you can use it inline with other text.